Прогнозирование температуры расплава стали
после окончания стадии легирования

Современное производство стали использует большое количество электрической энергии. Большая её часть идёт на нагрев и плавление сырья и вспомогательных реагентов, а также на поддержание температуры расплава на заданном уровне. Снижение уровня потребления электроэнергии позволит снизить расходы на неё, что приведёт к сокращению затрат на производство стали, снижению её себестоимости и, как следствие, повышению конкурентоспособности продукции металлургического предприятия.

Сталелитейное производство включает в себя процессы получения металлов из руд или других видов сырья, изменения их химического состава, структуры и свойств, а также последующее производство разнообразных металлических изделий из них. Основными этапами производства являются:

  • подготовка сырья — дробление и измельчение железной руды (шихты). Подготовленная шихта вместе с коксом и известью подаётся на стадию плавки (вместо руды может использоваться металлический лом);
  • плавка шихты — основная стадия производства стали. На сегодняшний день, плавка шихты происходит в дуговых сталеплавильных печах, в которых дополнительно создаются условия для удаления примесей, таких как сера. Затем расплав подаётся на стадию легирования;
  • легирование стали — введение специальных добавок в расплав стали для улучшения её механических, химических или тепловых свойств;
  • доводка стали (термическая обработка) — нагрев и охлаждение расплава стали с целью изменения её структуры и свойств. Может включать в себя такие процессы, как отжиг, закалка и отпуск, в зависимости от требуемых характеристик конечного продукта;
  • розлив стали в металлические формы — изложницы. Когда сталь затвердевает, формы снимаются, и изделия (металлические полупродукты) остывают до комнатной температуры. Если сталь предназначена для производства листового или прокатного металла, она может быть направлена в машину непрерывной разливки. Оттуда сталь выходит в виде слябов — полупродукта в форме плит прямоугольного сечения.

Одним из способов внепечной обработки стали, которая выполняется после выпуска расплава из плавильного агрегата, является легирование в ковше-печи (сталеразливочном ковше). Агрегат ковш-печь — это специальное металлургическое оборудование, которое используется для слива стали, её легирования, последующей транспортировки и разливки в слябы или другие формы. Он представляет собой объёмный металлический резервуар цилиндрической формы, изнутри футерованный огнеупорным кирпичом и снабжённый крышкой.

Легирование стали в ковше-печи происходит путём добавления легирующих материалов в расплав стали через отверстия в крышке ковша: через воронку подаются сыпучие материалы (металлы, неметаллы, а также сплавы), через трайб-аппарат подаются сыпучие или металлические проволоки.

Перемешивание расплава осуществляется продувкой через него инертного газа (азота или, чаще всего, аргона), подаваемого через установленные в днище ковша огнеупорные пробки или через отверстие (фурму) в крышке ковша. Продувка расплава инертным газом улучшает диффузию легирующих добавок в объём сплава, способствует удалению газовых включений и летучих примесей, помогает снижать температуру расплава.

Подогрев расплава осуществляется с помощью графитированных электродов, которые опускают к поверхности расплава через отверстия в крышке ковша. На электроды подаётся напряжение, образуется электрическая дуга, которая и передаёт электроэнергию расплаву.

Поскольку в процессе легирования стали протекают два конкурирующих процесса — нагрев расплава и его остывание, неотъемлемой частью стадии легирования является контроль температуры расплава. От температуры зависит растворимость легирующих добавок и их равномерное распределение в объёме расплавленной стали. Кроме того, регулирование температуры сплава позволяет добиться формирования структуры стали. Поэтому необходимо измерять температуру для того, чтобы, во-первых, определить готовность расплава к введению легирующих добавок и, во-вторых, определить готовность расплава к розливу и формованию или передачи его на доводку.

Температуру расплава в ковше-печи измеряют путём погружения в расплав термоэлектрического преобразователя (термопары) через специальное отверстие для термопар в крышке ковша-печи. Температуру расплава измеряют перед первым, а также перед каждым последующим введением легирующей добавки (в форме сыпучего материала или проволоки) и по окончании процесса легирования.

Процедура измерения температуры расплава затратная по времени: термопару необходимо опустить в ковш, термостатировать в расплаве и извлечь из ковша, чтобы продолжить легирование (добавлять сыпучие и проволочные материалы, перемешивать, подогревать расплав). А поскольку таких замеров температуры в ходе легирования при производстве одной партии стали может быть несколько, то и суммарное время, затрачиваемое на процедуру измерения температуры, может быть существенным.

В течение времени, когда расплав не подогревают, он теряет тепло, его температура снижается. Чтобы повысить температуру до требуемого уровня, расходуют электроэнергию. Чем больше времени расплав теряет энергию, тем больше энергии ему нужно сообщить.

Уменьшение времени, необходимого для измерения температуры расплава, позволяет снизить энергопотребление. Если процесс легирования на предприятии отлажен и воспроизводится с достаточно высокой точностью (подаются точно рассчитанные количества легирующих добавок, инертного газа и производится достаточный нагрев электродами), может быть принято решение об ослаблении промежуточного контроля температуры. Замер температуры может производиться только перед началом процесса легирования. Но поскольку необходимо знать температуру расплава, выходящего со стадии легирования, то вместо непосредственного её измерения можно использовать алгоритмы машинного обучения, которые по известной начальной температуре, сведениях о вносимых добавках, объёме пропускаемого газа и количестве переданной электроэнергии для подогрева расплава позволят предсказать конечную температуру.

В нашем распоряжении находятся данные о параметрах стадии легирования. Для каждой выпускаемой партии стали доступны сведения о поданных легирующих добавках, инертном газе, работе электродах и результатах измерения температуры.

Цель проекта: построить модель, прогнозирующую температуру расплава стали после окончания стадии легирования.

Задачи проекта:

  • выполнить предобработку данных;
  • подготовить набор данных для обучения алгоритмов;
  • провести описательный анализ данных;
  • разбить данные на тренировочную и тестовую выборки;
  • выбрать алгоритмы и построить модели;
  • выбрать метрики качества моделей и оценить их значения;
  • оценить значимость признаков для построения предсказания с использованием лучшей модели.

План работ¶

  1. Прочитать файлы и загрузить данные. Провести обзор наборов данных загруженных файлов.
  2. Раскрыть содержательный смысл признаков. Соотнести признаки с их типом и шкалой измерения.
  3. Описать данные с применением методов описательной статистики. Выявить аномальные значения. Определить потребность в признаках для формирования набора данных, на котором будут обучаться алгоритмы машинного обучения.
  4. Провести предварительную обработку данных. Обработать аномальные значения. Обогатить данные. Сформировать набор данных для обучения алгоритмов и построения предсказаний.
  5. Провести описательный и корреляционные анализы данных. Проанализировать значения признаков сформированного набора данных.
  6. Подготовить данные для обучения. Выделить в данных тестовую и тренировочную выборки.
  7. Обучить алгоритмы и оценить качество их предсказаний проведением кросс-валидации. Для алгоритмов, чувствительных к масштабу значений признаков, дополнительно выполнить масштабирование значений. Подобрать параметры наилучших моделей для каждого алгоритма.
  8. Продемонстрировать предсказательную способность лучшей построенной модели, отобранной по результатам оценки качества обученных алгоритмов. Проанализировать значимость признаков для построения качественного предсказания.
  9. Сделать вывод по проведённой работе.

Содержание

  • 1  Обзор данных
    • 1.1  Импорт библиотек и предварительные настройки
    • 1.2  Чтение файлов и загрузка данных
    • 1.3  Общая характеристика наборов данных
      • 1.3.1  Данные об электродах
      • 1.3.2  Данные о подаче сыпучих материалов (масса)
      • 1.3.3  Данные о подаче сыпучих материалов (время)
      • 1.3.4  Данные о проволочных материалах (масса)
      • 1.3.5  Данные о проволочных материалах (время)
      • 1.3.6  Данные о продувке сплава газом
      • 1.3.7  Результаты измерения температуры
  • 2  Понимание данных
  • 3  Описание данных
    • 3.1  Данные об электродах
      • 3.1.1  Номер партии
      • 3.1.2  Активная мощность
      • 3.1.3  Реактивная мощность
      • 3.1.4  Начало нагрева дугой
      • 3.1.5  Конец нагрева дугой
    • 3.2  Данные о подаче сыпучих материалов
      • 3.2.1  Номер партии
      • 3.2.2  Масса сыпучих материалов
      • 3.2.3  Время подачи сыпучих материалов
    • 3.3  Данные о подаче проволочных материалов
      • 3.3.1  Номер партии
      • 3.3.2  Масса проволочных материалов
      • 3.3.3  Время подачи проволочных материалов
    • 3.4  Данные о продувке сплава газом
      • 3.4.1  Номер партии
      • 3.4.2  Объём подаваемого газа
    • 3.5  Результаты измерения температуры
      • 3.5.1  Номер партии
      • 3.5.2  Температура
      • 3.5.3  Время замера
  • 4  Предобработка данных
    • 4.1  Обработка аномальных значений
      • 4.1.1  Температура
      • 4.1.2  Реактивная мощность
    • 4.2  Обогащение данных
      • 4.2.1  Полная мощность
      • 4.2.2  Коэффициент мощности
      • 4.2.3  Время подогрева
      • 4.2.4  Потреблённая энергия
      • 4.2.5  Сыпучие материалы
      • 4.2.6  Проволочные материалы
    • 4.3  Обработка пропусков
      • 4.3.1  Температура
      • 4.3.2  Масса сыпучих материалов
      • 4.3.3  Масса проволочных материалов
    • 4.4  Формирование набора данных для обучения алгоритмов
      • 4.4.1  Температура
      • 4.4.2  Время легирования
      • 4.4.3  Полная мощность
      • 4.4.4  Активная мощность
      • 4.4.5  Реактивная мощность
      • 4.4.6  Коэффициент мощности
      • 4.4.7  Время подогрева
      • 4.4.8  Потреблённая энергия
      • 4.4.9  Объём инертного газа
      • 4.4.10  Легирующие добавки
    • 4.5  Обзор набора данных для обучения алгоритмов
  • 5  Исследовательский анализ данных
    • 5.1  Описательный анализ
      • 5.1.1  Температура
      • 5.1.2  Время легирования
      • 5.1.3  Полная мощность
      • 5.1.4  Активная мощность
      • 5.1.5  Реактивная мощность
      • 5.1.6  Коэффициент мощности
      • 5.1.7  Время подогрева
      • 5.1.8  Потреблённая энергия
      • 5.1.9  Объём инертного газа
      • 5.1.10  Легирующие добавки
    • 5.2  Корреляционный анализ
  • 6  Построение моделей
    • 6.1  Подготовка данных для обучения
      • 6.1.1  Удаление лишних признаков
      • 6.1.2  Разделение данных на выборки
    • 6.2  Обучение моделей
      • 6.2.1  Валидация
      • 6.2.2  Простая модель
      • 6.2.3  Линейная регрессия
      • 6.2.4  Стохастический градиентный спуск
      • 6.2.5  Гребневая регрессия
      • 6.2.6  Регрессия LASSO
      • 6.2.7  Дерево решений
      • 6.2.8  Случайный лес
      • 6.2.9  Градиентный бустинг
        • 6.2.9.1  Базовая модель градиентного бустинга
        • 6.2.9.2  LightGBM
        • 6.2.9.3  XGBoost
        • 6.2.9.4  CatBoost
    • 6.3  Оценка модели
      • 6.3.1  Демонстрация работы модели
      • 6.3.2  Оценка значимости признаков
  • 7  Общий вывод

Внимание! Для корректной работы кода в ячейках рекомендуется предварительно установить следующие библиотеки:

In [1]:
!pip install scikit-learn --upgrade -q
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 10.8/10.8 MB 117.4 MB/s eta 0:00:00
In [2]:
!pip install lightgbm -q
In [3]:
!pip install catboost -q
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 98.7/98.7 MB 8.7 MB/s eta 0:00:00
In [4]:
!pip install xgboost -q

Обзор данных¶

Импорт библиотек и предварительные настройки¶

In [5]:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import sys
import os
import re
import warnings

from sklearn.model_selection import (train_test_split,
                                     RandomizedSearchCV,
                                     cross_val_score)
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler
from sklearn.base import BaseEstimator, RegressorMixin
from sklearn.dummy import DummyRegressor
from sklearn.linear_model import LinearRegression, SGDRegressor, Ridge, Lasso
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from catboost import CatBoostRegressor
from lightgbm import LGBMRegressor
from xgboost import XGBRegressor
from sklearn.metrics import mean_absolute_error

pd.set_option('display.max_columns', None)
np.set_printoptions(threshold=sys.maxsize)
warnings.filterwarnings('ignore')

RANDOM_STATE = 250923

Чтение файлов и загрузка данных¶

Все данные хранятся в семи файлах.
Файлы данных имеют формат CSV.

In [6]:
PATHS = [r'C:\Users\Георгий\Documents\DS_projects', '/datasets', '/content']

def read_df(name, paths=PATHS):
    '''
    Функция загрузки данных из CSV-файлов
    с проверкой существования пути к файлу.

    Принимает название файла.
    Возвращает набор данных из файла.
    '''

    for path in paths:
        file_path = os.path.join(path, name)
        if os.path.exists(file_path):
            df = pd.read_csv(file_path)

            return df

    print(f'{name}: Something is wrong')
In [7]:
data_arc = read_df('data_arc_new.csv')
data_bulk = read_df('data_bulk_new.csv')
data_bulk_time = read_df('data_bulk_time_new.csv')
data_gas = read_df('data_gas_new.csv')
data_temp = read_df('data_temp_new.csv')
data_wire = read_df('data_wire_new.csv')
data_wire_time = read_df('data_wire_time_new.csv')

Общая характеристика наборов данных¶

Предварительно зададим функции, позволяющие получить основные сведения о наборах данных, отслеживать в наборах данных наличие пропусков и визуализировать их распределение.

In [8]:
def df_info(data):
    '''
    Функция выводит описание набора данных, первые и посление строки,
    а также типы данных набора данных.

    Принимает набор исследуемых данных.
    '''

    display(data.head(2))
    display(data.tail(2))
    print('Размер набора данных:', data.shape)
    print('\nКоличество элементов данных:', data.size)
    print('\nКоличество дубликатов в наименованиях признаков:',
          data.columns.duplicated().sum())
    print('\nУникальные наименования признаков:\n',
          data.columns.sort_values().tolist())
    print('\nКоличество пропущенных значений:',
          data.isna().sum().sum())
    print('\nПроцент пропущенных значений:',
          round(data.isna().sum().sum() / data.size * 100, 1), '%')
    print('\nТипы данных набора данных:')
    display(data.dtypes.value_counts())
In [9]:
def show_na(data):
    '''
    Функция выводит количество пропусков в признаках и
    долю пропусков (в процентах) от общего числа записей.

    Принимает набор исследуемых данных.
    Возвращает датафрейм с описанием распределения пропусков.
    '''

    total = data.isna().sum().sort_values(ascending=False)
    percent = (data.isna().sum() /
               data.isna().count() * 100).round(1).sort_values(ascending=False)
    df = pd.concat([total, percent], axis=1, keys=['Всего пропусков', '%'])

    return df
In [10]:
def pic_na(data):
    '''
    Функция визуализирует распределение пропусков в наборе данных.

    Принимает набор исследуемых данных.
    '''

    sns.heatmap(data.isna(), cmap=sns.color_palette(['#000000', '#ffffff']))
    plt.title('Тепловая карта распределения пропущенных значений')
    plt.xlabel('Название признака')
    plt.ylabel('Номер записи')
    plt.show()

Данные об электродах¶

In [11]:
df_info(data_arc)
key Начало нагрева дугой Конец нагрева дугой Активная мощность Реактивная мощность
0 1 2019-05-03 11:02:14 2019-05-03 11:06:02 0.305130 0.211253
1 1 2019-05-03 11:07:28 2019-05-03 11:10:33 0.765658 0.477438
key Начало нагрева дугой Конец нагрева дугой Активная мощность Реактивная мощность
14874 3241 2019-09-06 17:21:58 2019-09-06 17:22:55 0.530267 0.361543
14875 3241 2019-09-06 17:24:54 2019-09-06 17:26:15 0.389057 0.251347
Размер набора данных: (14876, 5)

Количество элементов данных: 74380

Количество дубликатов в наименованиях признаков: 0

Уникальные наименования признаков:
 ['key', 'Активная мощность', 'Конец нагрева дугой', 'Начало нагрева дугой', 'Реактивная мощность']

Количество пропущенных значений: 0

Процент пропущенных значений: 0.0 %

Типы данных набора данных:
object     2
float64    2
int64      1
dtype: int64
In [12]:
show_na(data_arc)
Out[12]:
Всего пропусков %
key 0 0.0
Начало нагрева дугой 0 0.0
Конец нагрева дугой 0 0.0
Активная мощность 0 0.0
Реактивная мощность 0 0.0

Данные об электродах

  • Набор данных содержит 5 уникальных признаков и 14 876 записей.
  • В наборе данных: 74 380 элементов данных.
  • Набор данных содержит данные следующего типа:
    • целочисленный — 1 признак,
    • вещественный — 2 признака,
    • смешанного типа — 2 признака.
  • Все признаки содержат значения (не являются пустыми).
  • Все признаки не содержат пропущенные значения.

Данные о подаче сыпучих материалов (масса)¶

In [13]:
df_info(data_bulk)
key Bulk 1 Bulk 2 Bulk 3 Bulk 4 Bulk 5 Bulk 6 Bulk 7 Bulk 8 Bulk 9 Bulk 10 Bulk 11 Bulk 12 Bulk 13 Bulk 14 Bulk 15
0 1 NaN NaN NaN 43.0 NaN NaN NaN NaN NaN NaN NaN 206.0 NaN 150.0 154.0
1 2 NaN NaN NaN 73.0 NaN NaN NaN NaN NaN NaN NaN 206.0 NaN 149.0 154.0
key Bulk 1 Bulk 2 Bulk 3 Bulk 4 Bulk 5 Bulk 6 Bulk 7 Bulk 8 Bulk 9 Bulk 10 Bulk 11 Bulk 12 Bulk 13 Bulk 14 Bulk 15
3127 3240 NaN NaN NaN NaN NaN 26.0 NaN NaN NaN NaN NaN NaN NaN 192.0 54.0
3128 3241 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 180.0 52.0
Размер набора данных: (3129, 16)

Количество элементов данных: 50064

Количество дубликатов в наименованиях признаков: 0

Уникальные наименования признаков:
 ['Bulk 1', 'Bulk 10', 'Bulk 11', 'Bulk 12', 'Bulk 13', 'Bulk 14', 'Bulk 15', 'Bulk 2', 'Bulk 3', 'Bulk 4', 'Bulk 5', 'Bulk 6', 'Bulk 7', 'Bulk 8', 'Bulk 9', 'key']

Количество пропущенных значений: 35776

Процент пропущенных значений: 71.5 %

Типы данных набора данных:
float64    15
int64       1
dtype: int64
In [14]:
show_na(data_bulk)
Out[14]:
Всего пропусков %
Bulk 8 3128 100.0
Bulk 13 3111 99.4
Bulk 9 3110 99.4
Bulk 2 3107 99.3
Bulk 7 3104 99.2
Bulk 5 3052 97.5
Bulk 10 2953 94.4
Bulk 11 2952 94.3
Bulk 1 2877 91.9
Bulk 6 2553 81.6
Bulk 4 2115 67.6
Bulk 3 1831 58.5
Bulk 15 881 28.2
Bulk 12 679 21.7
Bulk 14 323 10.3
key 0 0.0
In [15]:
pic_na(data_bulk)

Данные о подаче сыпучих материалов (масса)

  • Набор данных содержит 16 уникальных признаков и 3129 записей.
  • В наборе данных: 50 064 элементов данных.
  • Набор данных содержит данные следующего типа:
    • целочисленный — 1 признак,
    • вещественный — 15 признаков.
  • Все признаки содержат значения (не являются пустыми).
  • 1 признак не содержит пропущенные значения — key.
  • 15 признаков содержат пропущенные значения:
    • распределение пропусков в данных не носит регулярный характер,
    • всего в данных 35 776 пропущенных значений — около 71,5 % от всех элементов данных,
    • меньше всего пропусков содержат признаки Bulk 12, Bulk 14, Bulk 15 — менее 30 % пропусков,
    • больше всего пропусков — более 95 % — содержат признаки Bulk 2, Bulk 5, Bulk 7, Bulk 9, Bulk 13, а в признаке Bulk 8 содержится только одно значение.

Данные о подаче сыпучих материалов (время)¶

In [16]:
df_info(data_bulk_time)
key Bulk 1 Bulk 2 Bulk 3 Bulk 4 Bulk 5 Bulk 6 Bulk 7 Bulk 8 Bulk 9 Bulk 10 Bulk 11 Bulk 12 Bulk 13 Bulk 14 Bulk 15
0 1 NaN NaN NaN 2019-05-03 11:28:48 NaN NaN NaN NaN NaN NaN NaN 2019-05-03 11:24:31 NaN 2019-05-03 11:14:50 2019-05-03 11:10:43
1 2 NaN NaN NaN 2019-05-03 11:36:50 NaN NaN NaN NaN NaN NaN NaN 2019-05-03 11:53:30 NaN 2019-05-03 11:48:37 2019-05-03 11:44:39
key Bulk 1 Bulk 2 Bulk 3 Bulk 4 Bulk 5 Bulk 6 Bulk 7 Bulk 8 Bulk 9 Bulk 10 Bulk 11 Bulk 12 Bulk 13 Bulk 14 Bulk 15
3127 3240 NaN NaN NaN NaN NaN 2019-09-06 16:24:28 NaN NaN NaN NaN NaN NaN NaN 2019-09-06 16:07:29 2019-09-06 16:01:34
3128 3241 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 2019-09-06 17:26:33 2019-09-06 17:23:15
Размер набора данных: (3129, 16)

Количество элементов данных: 50064

Количество дубликатов в наименованиях признаков: 0

Уникальные наименования признаков:
 ['Bulk 1', 'Bulk 10', 'Bulk 11', 'Bulk 12', 'Bulk 13', 'Bulk 14', 'Bulk 15', 'Bulk 2', 'Bulk 3', 'Bulk 4', 'Bulk 5', 'Bulk 6', 'Bulk 7', 'Bulk 8', 'Bulk 9', 'key']

Количество пропущенных значений: 35776

Процент пропущенных значений: 71.5 %

Типы данных набора данных:
object    15
int64      1
dtype: int64
In [17]:
show_na(data_bulk_time)
Out[17]:
Всего пропусков %
Bulk 8 3128 100.0
Bulk 13 3111 99.4
Bulk 9 3110 99.4
Bulk 2 3107 99.3
Bulk 7 3104 99.2
Bulk 5 3052 97.5
Bulk 10 2953 94.4
Bulk 11 2952 94.3
Bulk 1 2877 91.9
Bulk 6 2553 81.6
Bulk 4 2115 67.6
Bulk 3 1831 58.5
Bulk 15 881 28.2
Bulk 12 679 21.7
Bulk 14 323 10.3
key 0 0.0
In [18]:
pic_na(data_bulk_time)

Данные о подаче сыпучих материалов (время)

  • Набор данных содержит 16 уникальных признаков и 3129 записей.
  • В наборе данных: 50 064 элементов данных.
  • Набор данных содержит данные следующего типа:
    • целочисленный — 1 признак,
    • смешанного типа — 15 признаков.
  • Все признаки содержат значения (не являются пустыми).
  • 1 признак не содержит пропущенные значения — key.
  • 15 признаков содержат пропущенные значения:
    • распределение пропусков в данных не носит регулярный характер,
    • всего в данных 35 776 пропущенных значений — около 71,5 % от всех элементов данных,
    • меньше всего пропусков содержат признаки Bulk 12, Bulk 14, Bulk 15 — менее 30 % пропусков,
    • больше всего пропусков — более 95 % — содержат признаки Bulk 2, Bulk 5, Bulk 7, Bulk 9, Bulk 13, а в признаке Bulk 8 содержится только одно значение,
    • каждое значение набора данных о массе вносимых сыпучих материалов сопровождается соответствующей записью о времени их внесения, находящейся в текущем наборе данных.

Данные о проволочных материалах (масса)¶

In [19]:
df_info(data_wire)
key Wire 1 Wire 2 Wire 3 Wire 4 Wire 5 Wire 6 Wire 7 Wire 8 Wire 9
0 1 60.059998 NaN NaN NaN NaN NaN NaN NaN NaN
1 2 96.052315 NaN NaN NaN NaN NaN NaN NaN NaN
key Wire 1 Wire 2 Wire 3 Wire 4 Wire 5 Wire 6 Wire 7 Wire 8 Wire 9
3079 3240 34.070400 NaN NaN NaN NaN NaN NaN NaN NaN
3080 3241 63.117595 NaN NaN NaN NaN NaN NaN NaN NaN
Размер набора данных: (3081, 10)

Количество элементов данных: 30810

Количество дубликатов в наименованиях признаков: 0

Уникальные наименования признаков:
 ['Wire 1', 'Wire 2', 'Wire 3', 'Wire 4', 'Wire 5', 'Wire 6', 'Wire 7', 'Wire 8', 'Wire 9', 'key']

Количество пропущенных значений: 23385

Процент пропущенных значений: 75.9 %

Типы данных набора данных:
float64    9
int64      1
dtype: int64
In [20]:
show_na(data_wire)
Out[20]:
Всего пропусков %
Wire 5 3080 100.0
Wire 7 3070 99.6
Wire 4 3067 99.5
Wire 8 3062 99.4
Wire 9 3052 99.1
Wire 3 3018 98.0
Wire 6 3008 97.6
Wire 2 2002 65.0
Wire 1 26 0.8
key 0 0.0
In [21]:
pic_na(data_wire)

Данные о проволочных материалах (масса)

  • Набор данных содержит 10 уникальных признаков и 3081 запись.
  • В наборе данных: 30 810 элементов данных.
  • Набор данных содержит данные следующего типа:
    • целочисленный — 1 признак,
    • вещественный — 9 признаков.
  • Все признаки содержат значения (не являются пустыми).
  • 1 признак не содержит пропущенные значения — key.
  • 9 признаков содержат пропущенные значения:
    • распределение пропусков в данных не носит регулярный характер,
    • всего в данных 23 385 пропущенных значений — около 75,9 % от всех элементов данных,
    • самое маленькое количество пропусков — менее 1 % — содержит признак Wire 1,
    • немного больше трети — 35 % — значений содержит признак Wire 2,
    • все остальные признаки заполнены менее чем на 5 %, а в признаке Wire 5 содержится только одно значение.

Данные о проволочных материалах (время)¶

In [22]:
df_info(data_wire_time)
key Wire 1 Wire 2 Wire 3 Wire 4 Wire 5 Wire 6 Wire 7 Wire 8 Wire 9
0 1 2019-05-03 11:06:19 NaN NaN NaN NaN NaN NaN NaN NaN
1 2 2019-05-03 11:36:50 NaN NaN NaN NaN NaN NaN NaN NaN
key Wire 1 Wire 2 Wire 3 Wire 4 Wire 5 Wire 6 Wire 7 Wire 8 Wire 9
3079 3240 2019-09-06 15:33:55 NaN NaN NaN NaN NaN NaN NaN NaN
3080 3241 2019-09-06 17:10:06 NaN NaN NaN NaN NaN NaN NaN NaN
Размер набора данных: (3081, 10)

Количество элементов данных: 30810

Количество дубликатов в наименованиях признаков: 0

Уникальные наименования признаков:
 ['Wire 1', 'Wire 2', 'Wire 3', 'Wire 4', 'Wire 5', 'Wire 6', 'Wire 7', 'Wire 8', 'Wire 9', 'key']

Количество пропущенных значений: 23385

Процент пропущенных значений: 75.9 %

Типы данных набора данных:
object    9
int64     1
dtype: int64
In [23]:
show_na(data_wire_time)
Out[23]:
Всего пропусков %
Wire 5 3080 100.0
Wire 7 3070 99.6
Wire 4 3067 99.5
Wire 8 3062 99.4
Wire 9 3052 99.1
Wire 3 3018 98.0
Wire 6 3008 97.6
Wire 2 2002 65.0
Wire 1 26 0.8
key 0 0.0
In [24]:
pic_na(data_wire_time)

Данные о проволочных материалах (время)

  • Набор данных содержит 10 уникальных признаков и 3081 запись.
  • В наборе данных: 30 810 элементов данных.
  • Набор данных содержит данные следующего типа:
    • целочисленный — 1 признак,
    • вещественный — 9 признаков.
  • Все признаки содержат значения (не являются пустыми).
  • 1 признак не содержит пропущенные значения — key.
  • 9 признаков содержат пропущенные значения:
    • распределение пропусков в данных не носит регулярный характер,
    • всего в данных 23 385 пропущенных значений — около 75,9 % от всех элементов данных,
    • самое маленькое количество пропусков — менее 1 % — содержит признак Wire 1,
    • немного больше трети — 35 % — значений содержит признак Wire 2,
    • все остальные признаки заполнены менее чем на 5 %, а в признаке Wire 5 содержится только одно значение,
    • каждое значение набора данных о массе вносимых проволочных материалов сопровождается соответствующей записью о времени их внесения, находящейся в текущем наборе данных.

Данные о продувке сплава газом¶

In [25]:
df_info(data_gas)
key Газ 1
0 1 29.749986
1 2 12.555561
key Газ 1
3237 3240 11.863103
3238 3241 12.680959
Размер набора данных: (3239, 2)

Количество элементов данных: 6478

Количество дубликатов в наименованиях признаков: 0

Уникальные наименования признаков:
 ['key', 'Газ 1']

Количество пропущенных значений: 0

Процент пропущенных значений: 0.0 %

Типы данных набора данных:
int64      1
float64    1
dtype: int64
In [26]:
show_na(data_gas)
Out[26]:
Всего пропусков %
key 0 0.0
Газ 1 0 0.0

Данные о продувке сплава газом

  • Набор данных содержит 2 уникальных признака и 3239 записей.
  • В наборе данных: 6478 элементов данных.
  • Набор данных содержит данные следующего типа:
    • целочисленный — 1 признак,
    • вещественный — 1 признак.
  • Все признаки содержат значения (не являются пустыми).
  • Все признаки не содержат пропущенные значения.

Результаты измерения температуры¶

In [27]:
df_info(data_temp)
key Время замера Температура
0 1 2019-05-03 11:02:04 1571.0
1 1 2019-05-03 11:07:18 1604.0
key Время замера Температура
18090 3241 2019-09-06 17:24:44 NaN
18091 3241 2019-09-06 17:30:05 NaN
Размер набора данных: (18092, 3)

Количество элементов данных: 54276

Количество дубликатов в наименованиях признаков: 0

Уникальные наименования признаков:
 ['key', 'Время замера', 'Температура']

Количество пропущенных значений: 3427

Процент пропущенных значений: 6.3 %

Типы данных набора данных:
int64      1
object     1
float64    1
dtype: int64
In [28]:
show_na(data_temp)
Out[28]:
Всего пропусков %
Температура 3427 18.9
key 0 0.0
Время замера 0 0.0
In [29]:
pic_na(data_temp)

Данные о подаче сыпучих материалов (объём)

  • Набор данных содержит 3 уникальных признака и 18 092 записи.
  • В наборе данных: 54 276 элементов данных.
  • Набор данных содержит данные следующего типа:
    • целочисленный — 1 признак,
    • вещественный — 1 признак,
    • смешанного типа — 1 признак.
  • Все признаки содержат значения (не являются пустыми).
  • 2 признака не содержат пропущенные значения — key, Время замера.
  • 1 признак содержит пропущенные значения:
    • пропуски преимущественно находятся в конце набора данных,
    • всего в данных 3427 пропущенных значений — около 6,3 % от всех элементов данных,
    • пропуски содержатся только в признаке Температура и составляют почти 20 % от всех значений признака.

Промежуточный вывод

  • Во всех наборах данных содержится различное число записей: от 3081 до 18 092.
  • Все наборы данных содержат признак key — номер партии. Признак не содержит пропущенные значения. Может являться ключом, связывающим все наборы данных.
  • В наборах данных о работе электродов и о пропускаемом через расплав газе отсутствуют пропущенные значения.
  • В наборе данных о результатах измерения температуры отсутствуют сведения о значениях температуры почти для пятой части всех записей, приходящихся на последние выпускаемые партии. Однако для таких значений присутствуют сведения о времени регистрации температуры. Пропущенные значения могли появиться либо из-за ошибки регистрации, либо значения могли потеряться в результате сохранения и копирования данных.
  • Данные о вносимой массе материала и о времени его внесения хранятся в разных файлах, вероятно, по причине того, что эти данные получены от разных средств измерения. Причём каждая запись о вносимой массе материала в одном наборе данных сопровождается соответствующей записью о времени внесения в другом наборе данных.
  • В наборах данных о подаваемых для легирования материалах пропуски занимают до трёх четвертей от всех значений наборов данных. Очевидно, что наличие пропусков в записях связано с ведением технологического процесса: для выпуска определённой марки стали требуется использовать определённые (но не все) легирующие добавки.
  • Среди всех вносимых добавок можно выделить те, внесение которых практически всегда производится в процессе легирования — среди значений таких признаков меньше всего пропусков — это сыпучие материалы Bulk 12, Bulk 14, Bulk 15 и проволочный материал Wire 1. Остальные материалы используются менее часто, а некоторые совсем редко.

Понимание данных¶

Производство стали является периодическим. Поэтому продукт сталелитейного производства выходит партиями.

key — номер партии
Признак является категориальным, порядковым.
Шкала измерения признака: порядковая шкала.

Легирующие элементы могут быть введены в состав стали с помощью специальных сплавов или отдельных химических соединений. В ковш-печь легирующие добавки подаются с помощью специальных устройств, таких как трайб-аппараты или бункерные системы.

Подача сыпучих материалов может осуществляться из расходных бункеров сталелитейного цеха. Эти системы обеспечивают непрерывную подачу сыпучих материалов с заданной производительностью.

Bulk N — сыпучий материал номер N

Вносимая масса сыпучего материала (кг)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

Время внесения сыпучего материала (отметка времени с указанием даты)
Признак является количественным, непрерывным.
Шкала измерения признака: интервальная шкала.

Трайб-аппарат — это специальное устройство, предназначенное для ввода проволоки в расплав металла. Трайб-аппарат подаёт проволоку в расплав стали с определённой скоростью. Скорость подачи проволоки может регулироваться в зависимости от требуемых параметров процесса.

Wire N — проволочный материал номер N

Вносимая масса проволочного материала (кг)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

Время внесения проволочного материала (отметка времени с указанием даты)
Признак является количественным, непрерывным.
Шкала измерения признака: интервальная шкала.

Продувка расплава стали инертным газом позволяет достичь более равномерного распределения легирующих добавок и усреднения химического состава стали.

Газ 1 — объём продуваемого через расплав инертного газа (м$^3$)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

Продувка инертным газом сопровождается снижением температуры металла, так как газ нагревается и интенсивно уносит тепло. Подогревают расплав стали графитированными электродами.

Графитированные электроды являются токоведущими элементами и обеспечивают передачу электрического тока в расплав стали. Они размещаются таким образом, чтобы они находились над расплавленной сталью. Подача электрического тока через графитированные электроды создаёт дугу, которая и нагревает расплав.

Активная мощность графитированных электродов определяет электрическую энергию, которая преобразуется в тепло и используется для нагревания расплава стали.

Активная мощность — мощность, которая выделяется в дуге (МВт)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

Реактивная мощность не участвует в процессе плавки металла и является нежелательным эффектом, так как приводит к потерям энергии.

Реактивная мощность — мощность, которая возвращается обратно в сеть (МВт)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

Вместе со значениями активной и реактивной мощности в системе регистрируются время начала и время окончания подачи напряжения на электроды.

Начало нагрева дугой — отметка времени старта подачи напряжения на электроды
Признак является количественным, непрерывным.
Шкала измерения признака: интервальная шкала.

Конец нагрева дугой — отметка времени прекращения подачи напряжения на электроды
Признак является количественным, непрерывным.
Шкала измерения признака: интервальная шкала.

Перед введением каждой легирующей добавки измеряют температуру расплава. Перед непосредственным введением добавки через расплав пропускают электрический ток, тем самым нагревая его. Потом добавляют легирующий материал и продувают сплав инертным газом. Повторяют эту последовательность действий для каждой вводимой добавки. По окончании процесса легирования измеряют температуру получившегося сплава.

Температура — температура расплава ($^{\circ}$C)
Признак является количественным, непрерывным.
Шкала измерения признака: интервальная шкала.

Конечная температура сплава — целевой признак

Температуру регистрируют с одновременной регистрацией времени измерения.

Время замера — отметка времени регистрации температуры расплава
Признак является количественным, непрерывным.
Шкала измерения признака: интервальная шкала.

Хронометрические данные собраны от различных средств измерения. Их показания не синхронизированы. Возможны расхождения в показаниях.

Описание данных¶

In [30]:
def descriptive_statistics(values, label):
    '''
    Описательная статистика переменной, измеряемой в количественной шкале.

    Принимает значения признака и название признака.
    Возвращает DataFrame с набором статистик.

    '''

    df = pd.DataFrame([
        values.count(),
        len(values.unique()),
        values.min(),
        values.median() - 1.5 * (values.quantile(q=.75) -
                                 values.quantile(q=.25)),
        values.quantile(q=.25).round(2),
        (values.mode()).to_list(),
        values.median().round(2),
        values.mean().round(2),
        values.quantile(q=.75).round(2),
        values.median() + 1.5 * (values.quantile(q=.75) -
                                 values.quantile(q=.25)),
        values.max(),
        values.max() - values.min(),
        values.quantile(q=.75) - values.quantile(q=.25)
    ],
        index=['кол-во значений', 'кол-во уникальных', 'мин.',
               '-1.5IQR', '25 %', 'мода', 'медиана',
               'среднее ариф.', '75 %', '+1.5IQR', 'макс.',
               'размах', 'межквартильный размах'],
        columns=[label])

    return df
In [31]:
def graph(data, title, xlabel):
    '''
    Функция строит диаграмму распределения значений и диаграмму размаха
    исследуемых данных.

    Принимает набор исследуемых данных,
    название признака для заголовка графика,
    подпись оси Ox.
    '''

    fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(15, 6))
    ax1.set_title('Диаграмма распределения и диаграмма размаха' +
                  f'\nзначений {title}')
    ax1.hist(data, bins=100)
    ax1.tick_params(labelbottom=False)
    ax1.set_ylabel('Частота')
    ax2.boxplot(data, vert=False)
    ax2.tick_params(left=False, labelleft=False)
    ax2.set_xlabel(f'{xlabel}')
    plt.show()
In [32]:
def lot(data):
    '''
    Функция описывает номера партий.

    Принимает набор исследуемх данных.
    Возвращает датафрейм с характеристиками распределения значений партий.
    '''

    missing_key = []

    for i in range(data['key'].unique().min(),
                   data['key'].unique().max()+1):
        if i not in data['key'].unique():
            missing_key.append(i)

    return pd.DataFrame({
        'кол-во значений': data.shape[0],
        'кол-во уникальных': len(data['key'].unique()),
        'мин. значение': data['key'].min(),
        'макс. значение': data['key'].max(),
        'кол-во пропущенных': len(missing_key),
        'пропущенные партии': str(missing_key)
    }, index=['Номер партии']).T
In [33]:
def time(data, label):
    '''
    Функция описывает временной признак (секунды).

    Принимает набор исследуемых данных и название признака.
    Возвращает датафрейм с характеристиками распределения временных значений.
    '''

    return pd.DataFrame({
        'кол-во значений': data.shape[0],
        'кол-во уникальных': len(data.unique()),
        'первая запись': data.min(),
        'последняя запись': data.max()
    }, index=[label]).T
In [34]:
def day(data, label):
    '''
    Функция описывает временной признак (дни).

    Принимает набор исследуемых данных и название признака.
    Возвращает датафрейм с характеристиками распределения временных значений.
    '''

    data = pd.to_datetime(data)
    stat = pd.DataFrame(pd.to_datetime(data).dt.date.describe()).rename(
        columns={pd.DataFrame(data).columns[0]: label},
        index={'count': 'кол-во значений',
               'unique': 'кол-во уникальных',
               'top': 'мода',
               'freq': 'частота моды'}).T
    stat.loc[label, 'мода'] = stat.loc[label, 'мода'].strftime('%d.%m.%Y')
    stat['мин'] = data.min().strftime('%d.%m.%Y')
    stat['медиана'] = data.quantile(q=.5).strftime('%d.%m.%Y')
    stat['макс'] = data.max().strftime('%d.%m.%Y')
    stat['размах'] = (data.max() - data.min()).days + 1
    stat['межквартильный размах'] = (data.quantile(q=.75) -
                                     data.quantile(q=.25)).days

    return stat.T

Данные об электродах¶

Номер партии¶

In [35]:
lot(data_arc)
Out[35]:
Номер партии
кол-во значений 14876
кол-во уникальных 3214
мин. значение 1
макс. значение 3241
кол-во пропущенных 27
пропущенные партии [41, 42, 195, 279, 355, 382, 506, 529, 540, 60...
  • Значения определены для всех записей.
  • 14 876 записей характеризуют 3214 выпущенных партий. Одна партия может характеризоватся несколькими записями.
  • Номер первой выпущенной партии — 1, последней — 3214.
  • Не обо всех партиях в наборе данных присутствуют данные. Сведения о 27 выпущенных партиях отсутствуют.
  • Номера партий, о которых отсутствуют сведения, расположены произвольно. Характер их отсутствия не систематический.

Активная мощность¶

In [36]:
descriptive_statistics(data_arc['Активная мощность'],
                       'Активная мощность, МВт')
Out[36]:
Активная мощность, МВт
кол-во значений 14876
кол-во уникальных 13846
мин. 0.22312
-1.5IQR 0.055154
25 % 0.47
мода [0.509728, 0.712905]
медиана 0.6
среднее ариф. 0.66
75 % 0.83
+1.5IQR 1.144019
макс. 1.463773
размах 1.240653
межквартильный размах 0.362955
In [37]:
graph(data_arc['Активная мощность'],
      'активной мощности', 'Активная мощность, МВт')
  • Значения определены для всех записей.
  • Для 14 876 записей встречается 13 846 различных уникальных значений.
  • Минимальное значение — 0,22312 МВт, максимальное значение — 1,463773 МВт.
  • Медиана — 0,6 МВт, среднее арифметическое — 0,66 МВт.
  • Распределение унимодальное, несимметричное, с длинным "хвостом" справа.
  • Половина всех значений лежит в пределах от 0,47 до 0,83 МВт.
  • Практически все значения не превышают 1,14 МВт.

Реактивная мощность¶

In [38]:
descriptive_statistics(data_arc['Реактивная мощность'],
                       'Реактивная мощность, МВт')
Out[38]:
Реактивная мощность, МВт
кол-во значений 14876
кол-во уникальных 14707
мин. -715.479924
-1.5IQR 0.035101
25 % 0.34
мода [0.257418, 0.310365]
медиана 0.44
среднее ариф. 0.44
75 % 0.61
+1.5IQR 0.848178
макс. 1.270284
размах 716.750208
межквартильный размах 0.271026
In [39]:
graph(data_arc['Реактивная мощность'],
      'реактивной мощности', 'Реактивная мощность, МВт')
  • Значения определены для всех записей.
  • Для 14 876 записей встречается 14 707 различных уникальных значений.
  • Минимальное значение — (−715,479924 МВт) — очевидно, является аномальным и связано с ошибкой либо работы датчика, либо процедуры записи и копирования данных.

Посмотрим на значения, физически достижимые на практике: положительные значения реактивной мощности.

In [40]:
descriptive_statistics(data_arc.loc[data_arc['Реактивная мощность'] > 0,
                                    'Реактивная мощность'],
                       'Реактивная мощность, МВт')
Out[40]:
Реактивная мощность, МВт
кол-во значений 14875
кол-во уникальных 14706
мин. 0.153777
-1.5IQR 0.035115
25 % 0.34
мода [0.257418, 0.310365]
медиана 0.44
среднее ариф. 0.49
75 % 0.61
+1.5IQR 0.848215
макс. 1.270284
размах 1.116507
межквартильный размах 0.271033
In [41]:
graph(data_arc.loc[data_arc['Реактивная мощность'] > 0, 'Реактивная мощность'],
      'реактивной мощности', 'Реактивная мощность, МВт')
  • Для 14 876 записей встречается 14 706 различных уникальных положительных значений.
  • Минимальное значение — 0,153777 МВт, максимальное значение — 1,270284 МВт.
  • Медиана — 0,44 МВт, среднее арифметическое — 0,49 МВт.
  • Распределение унимодальное, несимметричное, с длинным "хвостом" справа.
  • Половина всех значений лежит в пределах от 0,34 до 0,61 МВт.
  • Практически все значения не превышают 0,85 МВт.

Начало нагрева дугой¶

In [42]:
time(data_arc.loc[data_arc['Начало нагрева дугой'].notna(),
                  'Начало нагрева дугой'], 'Начало нагрева дугой')
Out[42]:
Начало нагрева дугой
кол-во значений 14876
кол-во уникальных 14876
первая запись 2019-05-03 11:02:14
последняя запись 2019-09-06 17:24:54
In [43]:
day(data_arc.loc[data_arc['Начало нагрева дугой'].notna(),
                 'Начало нагрева дугой'], 'Начало нагрева дугой')
Out[43]:
Начало нагрева дугой
кол-во значений 14876
кол-во уникальных 123
мода 06.06.2019
частота моды 167
мин 03.05.2019
медиана 03.07.2019
макс 06.09.2019
размах 127
межквартильный размах 64
  • Значения определены для всех записей.
  • Значения определены с точностью до 1 с.
  • Все отметки времени являются уникальными.
  • Всего в наборе данных представлены сведения о 123 днях.
  • Наблюдения проводились в период 127 дней.
  • Первое наблюдение выполнено 3 мая 2019 года, последнее — 6 сентября 2019 года.
  • Медианное значение — 3 июля 2019 года — приходится почти на середину периода.
  • Чаще всего измерения проводились 6 июня 2019 года; было зарегистрировано 167 показаний.

Конец нагрева дугой¶

In [44]:
time(data_arc.loc[data_arc['Конец нагрева дугой'].notna(),
                  'Конец нагрева дугой'], 'Конец нагрева дугой')
Out[44]:
Конец нагрева дугой
кол-во значений 14876
кол-во уникальных 14876
первая запись 2019-05-03 11:06:02
последняя запись 2019-09-06 17:26:15
In [45]:
day(data_arc.loc[data_arc['Конец нагрева дугой'].notna(),
                 'Конец нагрева дугой'], 'Конец нагрева дугой')
Out[45]:
Конец нагрева дугой
кол-во значений 14876
кол-во уникальных 123
мода 06.06.2019
частота моды 168
мин 03.05.2019
медиана 03.07.2019
макс 06.09.2019
размах 127
межквартильный размах 64
  • Значения определены для всех записей.
  • Значения определены с точностью до 1 с.
  • Все отметки времени являются уникальными.
  • Всего в наборе данных представлены сведения о 123 днях.
  • Наблюдения проводились в период 127 дней.
  • Первое наблюдение выполнено 3 мая 2019 года, последнее — 6 сентября 2019 года.
  • Медианное значение — 3 июля 2019 года — приходится почти на середину периода.
  • Чаще всего измерения проводились 6 июня 2019 года; было зарегистрировано 168 показаний.

Данные о подаче сыпучих материалов¶

Номер партии¶

In [46]:
lot(data_bulk)
Out[46]:
Номер партии
кол-во значений 3129
кол-во уникальных 3129
мин. значение 1
макс. значение 3241
кол-во пропущенных 112
пропущенные партии [41, 42, 51, 52, 53, 54, 55, 56, 72, 80, 81, 1...
  • Значения определены для всех записей.
  • 3129 значений характеризуют 3129 выпущенных партий. Каждая партия характеризуется одной записью.
  • Номер первой выпущенной партии — 1, последней — 3241.
  • Не обо всех партиях в наборе данных присутствуют данные. Сведения о 112 выпущенных партиях отсутствуют.
  • Номера партий, о которых отсутствуют сведения, расположены произвольно. Характер их отсутствия не систематический.
In [47]:
lot(data_bulk_time)
Out[47]:
Номер партии
кол-во значений 3129
кол-во уникальных 3129
мин. значение 1
макс. значение 3241
кол-во пропущенных 112
пропущенные партии [41, 42, 51, 52, 53, 54, 55, 56, 72, 80, 81, 1...
  • Значения определены для всех записей.
  • 3129 значений характеризуют 3129 выпущенных партий. Каждая партия характеризуется одной записью.
  • Номер первой выпущенной партии — 1, последней — 3241.
  • Не обо всех партиях в наборе данных присутствуют данные. Сведения о 112 выпущенных партиях отсутствуют.
  • Номера партий, о которых отсутствуют сведения, расположены произвольно. Характер их отсутствия не систематический.
  • Каждое значение массы внесённого сыпучего материала сопровождается записью о времени его внесения.

Масса сыпучих материалов¶

In [48]:
df = pd.DataFrame()

for i in range(1, 16):
    df = df.join(
        descriptive_statistics(
            data_bulk.loc[data_bulk[f'Bulk {i}'].notna(), f'Bulk {i}'],
            f'{i}'),
        how='right').rename_axis('Сыпучий материал', axis=1)

df
Out[48]:
Сыпучий материал 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
кол-во значений 252 22 1298 1014 77 576 25 1 19 176 177 2450 18 2806 2248
кол-во уникальных 47 15 278 206 55 205 25 1 10 77 101 331 14 284 156
мин. 10.0 228.0 6.0 12.0 11.0 17.0 47.0 49.0 63.0 24.0 8.0 53.0 151.0 16.0 1.0
-1.5IQR 2.5 227.875 -43.5 10.5 -7.0 -30.875 -78.5 49.0 61.25 29.5 -57.5 40.0 80.125 20.875 10.0
25 % 27.0 242.0 58.0 72.0 70.0 69.75 155.0 49.0 66.0 64.0 25.0 204.0 153.25 119.0 105.0
мода [27.0] [254.0] [21.0] [88.0, 116.0] [74.0] [76.0] [47.0, 50.0, 54.0, 75.0, 92.0, 108.0, 155.0, 1... [49.0] [66.0, 68.0] [105.0] [18.0] [206.0] [153.0, 154.0] [102.0] [104.0]
медиана 31.0 251.5 97.5 102.0 86.0 100.0 298.0 49.0 68.0 86.5 64.0 208.0 155.5 151.0 160.0
среднее ариф. 39.24 253.05 113.88 104.39 107.03 118.93 305.6 49.0 76.32 83.28 76.82 260.47 181.11 170.28 160.51
75 % 46.0 257.75 152.0 133.0 132.0 157.0 406.0 49.0 70.5 102.0 106.0 316.0 203.5 205.75 205.0
+1.5IQR 59.5 275.125 238.5 193.5 179.0 230.875 674.5 49.0 74.75 143.5 185.5 376.0 230.875 281.125 310.0
макс. 185.0 325.0 454.0 281.0 603.0 503.0 772.0 49.0 147.0 159.0 313.0 1849.0 305.0 636.0 405.0
размах 175.0 97.0 448.0 269.0 592.0 486.0 725.0 0.0 84.0 135.0 305.0 1796.0 154.0 620.0 404.0
межквартильный размах 19.0 15.75 94.0 61.0 62.0 87.25 251.0 0.0 4.5 38.0 81.0 112.0 50.25 86.75 100.0
In [49]:
for i in range(1, 16):
    graph(data_bulk.loc[data_bulk[f'Bulk {i}'].notna(), f'Bulk {i}'],
          f'массы сыпучего материала номер {i}',
          f'Масса сыпучего материала номер {i}, кг')

Bulk 1 — масса сыпучего материала номер 1

  • Значения определены для 252 записей из 3129 — это 8 % всех значений.
  • Для 252 записей встречается 47 различных уникальных значений.
  • Минимальное значение — 10 кг, максимальное значение — 185 кг.
  • Мода — 27 кг, её частота почти 80.
  • Медиана — 31 кг, среднее арифметическое — 39,24 кг.
  • Из-за малого числа значений форму распределения трудно охарактеризовать. Но сравнительно большое количество значений приходится на моду.
  • Половина всех значений лежит в диапазоне 27–46 кг.
  • Практически все значения не превышают 60 кг.

Bulk 2 — масса сыпучего материала номер 2

  • Значения определены для 22 записей из 3129 — это 0,7 % всех значений.
  • Для 22 записей встречается 15 различных уникальных значений.
  • Минимальное значение — 228 кг, максимальное значение — 325 кг.
  • Мода — 254 кг, её частота 4.
  • Медиана — 251,5 кг, среднее арифметическое — 253,05 кг.
  • Из-за малого числа значений форму распределения трудно охарактеризовать. Наблюдаются отдельные дискретно распределённые значения.
  • Половина всех значений лежит в диапазоне 242–258 кг.
  • Практически все значения не превышают 275 кг.

Bulk 3 — масса сыпучего материала номер 3

  • Значения определены для 1298 записей из 3129 — это 41 % всех значений.
  • Для 1298 записей встречается 278 различных уникальных значений.
  • Минимальное значение — 6 кг, максимальное значение — 454 кг.
  • Мода — 21 кг, её частота почти 60.
  • Медиана — 97,5 кг, среднее арифметическое — 113,88 кг.
  • Распределение без чётко выраженной моды, смещено влево, с длинным "хвостом" справа.
  • Половина всех значений лежит в диапазоне 58–152 кг.
  • Практически все значения не превышают 239 кг.

Bulk 4 — масса сыпучего материала номер 4

  • Значения определены для 1014 записей из 3129 — это 32 % всех значений.
  • Для 1014 записей встречается 206 различных уникальных значений.
  • Минимальное значение — 12 кг, максимальное значение — 281 кг.
  • Моды — 88 и 116 кг, их частота почти 40.
  • Медиана — 102 кг, среднее арифметическое — 104,39 кг.
  • Распределение без чётко выраженной моды. Значения почти симметрично распределены относительно медианы. Наблюдается небольшой "хвост" справа.
  • Половина всех значений лежит в диапазоне 72–133 кг.
  • Практически все значения не превышают 193 кг.

Bulk 5 — масса сыпучего материала номер 5

  • Значения определены для 77 записей из 3129 — это 2 % всех значений.
  • Для 77 записей встречается 55 различных уникальных значений.
  • Минимальное значение — 11 кг, максимальное значение — 603 кг.
  • Мода — 74 кг, её частота почти 10.
  • Медиана — 86 кг, среднее арифметическое — 107,03 кг.
  • Распределение без чётко выраженной моды. Значения почти симметрично распределены относительно медианы. Наблюдается несколько сильно отстоящих значений справа.
  • Половина всех значений лежит в диапазоне 70–132 кг.
  • Практически все значения не превышают 179 кг.

Bulk 6 — масса сыпучего материала номер 6

  • Значения определены для 576 записей из 3129 — это 18 % всех значений.
  • Для 576 записей встречается 205 различных уникальных значений.
  • Минимальное значение — 17 кг, максимальное значение — 503 кг.
  • Мода — 76 кг, её частота почти 35.
  • Медиана — 100 кг, среднее арифметическое — 118,93 кг.
  • Распределение без чётко выраженной моды, смещено влево, с длинным "хвостом" справа.
  • Половина всех значений лежит в диапазоне 70–157 кг.
  • Практически все значения не превышают 230 кг.

Bulk 7 — масса сыпучего материала номер 7

  • Значения определены для 25 записей из 3129 — это 0,8 % всех значений.
  • Для 25 записей встречается 25 различных уникальных значений.
  • Минимальное значение — 47 кг, максимальное значение — 772 кг.
  • Моды нет. Все значения уникальные.
  • Медиана — 298 кг, среднее арифметическое — 305,6 кг.
  • Наблюдаются отдельные дискретно распределённые значения. Каждое значение встречается один раз.
  • Половина всех значений лежит в диапазоне 155–406 кг.
  • Практически все значения не превышают 674 кг.

Bulk 8 — масса сыпучего материала номер 8

  • Значения определены для 1 записи из 3129 — это менее 0,1 % всех значений.
  • Встречается только одно значение — 49 кг.

Bulk 9 — масса сыпучего материала номер 9

  • Значения определены для 19 записей из 3129 — это 0,6 % всех значений.
  • Для 19 записей встречается 10 различных уникальных значений.
  • Минимальное значение — 63 кг, максимальное значение — 147 кг.
  • Моды — 66 и 68 кг, их частота 4.
  • Медиана — 68 кг, среднее арифметическое — 76,32 кг.
  • Из-за малого числа значений форму распределения трудно охарактеризовать. Наблюдаются отдельные дискретно распределённые значения. Почти все из них расположены около медианы. Наблюдаются также несколько сильно отстоящих значений справа.
  • Половина всех значений лежит в диапазоне 66–70 кг.
  • Практически все значения не превышают 74 кг.

Bulk 10 — масса сыпучего материала номер 10

  • Значения определены для 176 записей из 3129 — это 6 % всех значений.
  • Для 176 записей встречается 77 различных уникальных значений.
  • Минимальное значение — 24 кг, максимальное значение — 159 кг.
  • Мода — 105 кг, её частота почти 15.
  • Медиана — 86,5 кг, среднее арифметическое — 83,28 кг.
  • Из-за малого числа значений форму распределения трудно охарактеризовать. Значения почти симметрично распределены относительно медианы.
  • Половина всех значений лежит в диапазоне 64–102 кг.
  • Практически все значения не превышают 143 кг.

Bulk 11 — масса сыпучего материала номер 11

  • Значения определены для 177 записей из 3129 — это 6 % всех значений.
  • Для 177 записей встречается 101 различное уникальное значение.
  • Минимальное значение — 8 кг, максимальное значение — 313 кг.
  • Мода — 18 кг, её частота почти 15.
  • Медиана — 64 кг, среднее арифметическое — 76,82 кг.
  • Из-за малого числа значений форму распределения трудно охарактеризовать. Распределение без чётко выраженной моды.
  • Половина всех значений лежит в диапазоне 25–106 кг.
  • Практически все значения не превышают 185 кг.

Bulk 12 — масса сыпучего материала номер 12

  • Значения определены для 2450 записей из 3129 — это 78 % всех значений.
  • Для 2450 записей встречается 331 различное уникальное значение.
  • Минимальное значение — 53 кг, максимальное значение — 1849 кг.
  • Мода — 206 кг, её частота почти 800.
  • Медиана — 208 кг, среднее арифметическое — 260,47 кг.
  • Распределение носит дискретный характер. Наблюдается наличие несколько ярко выраженных значений. Значения распределены почти симметрично относительно своей моды. Наблюдается "хвост" справа.
  • Половина всех значений лежит в диапазоне 204–316 кг.
  • Практически все значения не превышают 376 кг.

Bulk 13 — масса сыпучего материала номер 13

  • Значения определены для 18 записей из 3129 — это 0,6 % всех значений.
  • Для 18 записей встречается 14 различных уникальных значений.
  • Минимальное значение — 151 кг, максимальное значение — 305 кг.
  • Моды — 153 и 154 кг, их частота 6.
  • Медиана — 155,5 кг, среднее арифметическое — 181,11 кг.
  • Распределение носит дискретный характер. Большинство значений приходится на моды.
  • Половина всех значений лежит в диапазоне 153–203 кг.
  • Практически все значения не превышают 230 кг.

Bulk 14 — масса сыпучего материала номер 14

  • Значения определены для 2806 записей из 3129 — это 90 % всех значений.
  • Для 2806 записей встречается 284 различных уникальных значений.
  • Минимальное значение — 16 кг, максимальное значение — 636 кг.
  • Мода — 102 кг, её частота почти 350.
  • Медиана — 151 кг, среднее арифметическое — 170,28 кг.
  • Распределение носит дискретный характер. Большинство значений распределены около нескольких дискретных значений. Наблюдается длинный "хвост" справа.
  • Половина всех значений лежит в диапазоне 119–205 кг.
  • Практически все значения не превышают 281 кг.

Bulk 15 — масса сыпучего материала номер 15

  • Значения определены для 2248 записей из 3129 — это 72 % всех значений.
  • Для 2248 записей встречается 156 различных уникальных значений.
  • Минимальное значение — 1 кг, максимальное значение — 405 кг.
  • Мода — 104 кг, её частота почти 650.
  • Медиана — 160 кг, среднее арифметическое — 160,51 кг.
  • Распределение носит дискретный характер. Большинство значений распределено около нескольких дискретных значений. Наибольшее их число распределены около 100 и 200 кг.
  • Половина всех значений (относительно медианы) лежит в диапазоне 105–205 кг.
  • Практически все значения не превышают 310 кг.

Время подачи сыпучих материалов¶

In [50]:
df = pd.DataFrame()

for i in range(1, 16):
    df = df.join(
        time(data_bulk_time.loc[data_bulk_time[f'Bulk {i}'].notna(),
                                f'Bulk {i}'], f'{i}'),
        how='right').rename_axis('Сыпучий материал', axis=0)

df.T
Out[50]:
Сыпучий материал кол-во значений кол-во уникальных первая запись последняя запись
1 252 252 2019-05-03 17:42:46 2019-09-05 09:11:32
2 22 22 2019-05-07 15:39:35 2019-08-13 11:47:39
3 1298 1298 2019-05-03 20:40:25 2019-09-06 12:26:52
4 1014 1014 2019-05-03 11:28:48 2019-09-05 03:35:21
5 77 77 2019-05-07 15:19:17 2019-09-02 18:16:52
6 576 576 2019-05-03 19:09:15 2019-09-06 16:24:28
7 25 25 2019-05-07 18:11:01 2019-09-05 19:07:49
8 1 1 2019-07-08 17:14:53 2019-07-08 17:14:53
9 19 19 2019-05-14 11:57:58 2019-08-16 09:11:56
10 176 176 2019-05-06 07:54:02 2019-09-04 10:03:22
11 177 177 2019-05-05 23:43:24 2019-09-06 05:03:14
12 2450 2450 2019-05-03 11:24:31 2019-09-06 15:01:44
13 18 18 2019-05-05 02:10:21 2019-09-01 01:53:02
14 2806 2806 2019-05-03 11:14:50 2019-09-06 17:26:33
15 2248 2248 2019-05-03 11:10:43 2019-09-06 17:23:15
In [51]:
df = pd.DataFrame()

for i in range(1, 16):
    df = df.join(
        day(data_bulk_time.loc[data_bulk_time[f'Bulk {i}'].notna(),
                               f'Bulk {i}'], f'{i}'),
        how='right').rename_axis('Сыпучий материал', axis=0)

df.T
Out[51]:
Сыпучий материал кол-во значений кол-во уникальных мода частота моды мин медиана макс размах межквартильный размах
1 252 91 06.07.2019 9 03.05.2019 25.06.2019 05.09.2019 125 62
2 22 5 27.07.2019 7 07.05.2019 27.07.2019 13.08.2019 98 76
3 1298 120 06.06.2019 27 03.05.2019 04.07.2019 06.09.2019 126 63
4 1014 117 19.06.2019 24 03.05.2019 28.06.2019 05.09.2019 125 65
5 77 22 02.09.2019 9 07.05.2019 25.07.2019 02.09.2019 119 54
6 576 104 24.07.2019 21 03.05.2019 09.07.2019 06.09.2019 126 61
7 25 9 27.07.2019 7 07.05.2019 27.07.2019 05.09.2019 122 23
8 1 1 08.07.2019 1 08.07.2019 08.07.2019 08.07.2019 1 0
9 19 4 14.05.2019 10 14.05.2019 14.05.2019 16.08.2019 94 93
10 176 53 21.05.2019 10 06.05.2019 06.07.2019 04.09.2019 122 62
11 177 72 24.07.2019 12 05.05.2019 24.07.2019 06.09.2019 124 57
12 2450 123 01.09.2019 31 03.05.2019 03.07.2019 06.09.2019 127 66
13 18 17 11.05.2019 2 05.05.2019 01.07.2019 01.09.2019 119 67
14 2806 123 06.07.2019 32 03.05.2019 03.07.2019 06.09.2019 127 65
15 2248 123 01.09.2019 29 03.05.2019 03.07.2019 06.09.2019 127 65
  • Значения массы каждого сыпучего материала определены не для всех записей. Но если определено значение вносимой массы, то каждая запись о вносимой массе сопровождается записью об отметке времени внесения.
  • Значения определены с точностью до 1 с.
  • Для каждого каждого сыпучего материала все отметки времени являются уникальными.
  • Все наблюдения проводились в период 127 дней.
  • В наборе данных представлены сведения:
    • о 123 днях (максимум) — для сыпучих материалов номер 12, 14, 15,
    • о немного меньшем количестве дней — 91, 104, 117, 120 — для материалов номер 1, 6, 4, 3, соответственно,
    • о ещё меньшем количестве дней — 53, 72 — для материалов номер 10, 11, соответственно,
    • о небольшом количестве дней — 17, 22 — для материалов 13, 5, соответственно,
    • о совсем маленьком количестве дней — 1, 4, 5, 9 — для материалов 8, 9, 2, 7, соответственно.
  • Сведения о сыпучих материалах появляются в период с 3 по 14 мая 2019 года:
    • с 3 мая 2019 года — о материалах номер 1, 3, 4, 6, 12, 14, 15,
    • с 5 мая 2019 года — о материалах номер 11, 13,
    • с 6 мая 2019 года — о материале номер 10,
    • с 7 мая 2019 года — о материалах номер 2, 5, 7,
    • с 14 мая 2019 года — о материале номер 9.
  • Последняя запись о сыпучих материалах появляется в период с 13 августа по 6 сентября 2019 года:
    • 13 августа 2019 года — о материале 2,
    • 16 августа 2019 года — о материале 9,
    • 1 сентября 2019 года — о материале 13,
    • 2 сентября 2019 года — о материале 5,
    • 4 сентября 2019 года — о материале 10,
    • 5 сентября 2019 года — о материалах 1, 4, 7,
    • 6 сентября 2019 года — о материалах 3, 6, 11, 12, 14, 15.
  • Сведения о сыпучем материале номер 8 появляются единожды — 8 июля 2019 года.
  • В течение одного дня наибольшее число упоминаний о сыпучем материале изменяется от 1 до 32.

Данные о подаче проволочных материалов¶

Номер партии¶

In [52]:
lot(data_wire)
Out[52]:
Номер партии
кол-во значений 3081
кол-во уникальных 3081
мин. значение 1
макс. значение 3241
кол-во пропущенных 160
пропущенные партии [41, 42, 51, 52, 53, 54, 55, 56, 81, 82, 83, 8...
  • Значения определены для всех записей.
  • 3081 значение характеризует 3081 выпущенную партию. Каждая партия характеризуется одной записью.
  • Номер первой выпущенной партии — 1, последней — 3241.
  • Не обо всех партиях в наборе данных присутствуют данные. Сведения о 160 выпущенных партиях отсутствуют.
  • Номера партий, о которых отсутствуют сведения, расположены произвольно. Характер их отсутствия не систематический.
In [53]:
lot(data_wire_time)
Out[53]:
Номер партии
кол-во значений 3081
кол-во уникальных 3081
мин. значение 1
макс. значение 3241
кол-во пропущенных 160
пропущенные партии [41, 42, 51, 52, 53, 54, 55, 56, 81, 82, 83, 8...
  • Значения определены для всех записей.
  • 3081 значение характеризует 3081 выпущенную партию. Каждая партия характеризуется одной записью.
  • Номер первой выпущенной партии — 1, последней — 3241.
  • Не обо всех партиях в наборе данных присутствуют данные. Сведения о 160 выпущенных партиях отсутствуют.
  • Номера партий, о которых отсутствуют сведения, расположены произвольно. Характер их отсутствия не систематический.
  • Каждое значение массы внесённого проволочного материала сопровождается записью о времени его внесения.

Масса проволочных материалов¶

In [54]:
df = pd.DataFrame()

for i in range(1, 10):
    df = df.join(
        descriptive_statistics(
            data_wire.loc[data_wire[f'Wire {i}'].notna(), f'Wire {i}'],
            f'{i}'),
        how='right').rename_axis('Проволочный материал', axis=1)

df
Out[54]:
Проволочный материал 1 2 3 4 5 6 7 8 9
кол-во значений 3055 1079 63 14 1 73 11 19 29
кол-во уникальных 2251 713 56 14 1 69 10 13 25
мин. 1.9188 0.03016 0.144144 24.148801 15.132 0.03432 0.234208 45.076721 4.6228
-1.5IQR 19.241035 -34.907861 -36.480479 -7.742143 15.132 -16.662361 1.332057 43.287913 -2.639004
25 % 72.12 20.19 95.14 40.81 15.13 25.05 6.76 46.09 22.06
мода [105.0504] [30.09968] [0.144144, 93.165077] [24.148801, 25.132641, 33.182243, 40.069122, 4... [15.132] [18.086641, 20.145842, 25.0536, 38.198162] [12.354473] [46.187439000000005] [30.066399]
медиана 100.16 40.14 235.19 45.23 15.13 42.08 9.02 46.28 30.07
среднее ариф. 100.9 50.58 189.48 57.44 15.13 48.02 10.04 53.63 34.16
75 % 126.06 70.23 276.25 76.12 15.13 64.21 11.89 48.09 43.86
+1.5IQR 181.075433 115.193773 506.870433 98.210708 15.132 100.815009 16.70196 49.272085 62.771802
макс. 330.314424 282.780152 385.008668 113.231044 15.132 180.454575 32.847674 102.762401 90.053604
размах 328.395624 282.749992 384.864524 89.082243 0.0 180.420255 32.613466 57.68568 85.430804
межквартильный размах 53.944799 50.033878 181.11697 35.317617 0.0 39.159123 5.123301 1.994724 21.803602
In [55]:
for i in range(1, 10):
    graph(data_wire.loc[data_wire[f'Wire {i}'].notna(), f'Wire {i}'],
          f'массы проволочного материала номер {i}',
          f'Масса проволочного материала номер {i}, кг')

Wire 1 — масса проволочного материала номер 1

  • Значения определены для 3055 записей из 3081 — это 99 % всех значений.
  • Для 3055 записей встречается 2251 различное уникальное значение.
  • Минимальное значение — 1,9188 кг, максимальное значение — 330,314424 кг.
  • Мода — 105,0504 кг, её частота почти 150.
  • Медиана — 100,16 кг, среднее арифметическое — 100,9 кг.
  • Распределение унимодальное, почти симметричное. Наблюдается "хвост" справа.
  • Половина всех значений лежит в диапазоне 72–126 кг.
  • Практически все значения не превышают 181 кг.

Wire 2 — масса проволочного материала номер 2

  • Значения определены для 1079 записей из 3081 — это 35 % всех значений.
  • Для 1079 записей встречается 713 различных уникальных значений.
  • Минимальное значение — 0,03016 кг, максимальное значение — 282,780152 кг.
  • Мода — 30,09968 кг, её частота почти 100.
  • Медиана — 40,14 кг, среднее арифметическое — 50,58 кг.
  • Распределение без чётко выраженной моды. Наблюдается смещение значений влево и длинный "хвост" справа.
  • Половина всех значений лежит в диапазоне 20–70 кг.
  • Практически все значения не превышают 115 кг.

Wire 3 — масса проволочного материала номер 3

  • Значения определены для 63 записей из 3081 — это 2 % всех значений.
  • Для 63 записей встречается 56 различных уникальных значений.
  • Минимальное значение — 0,144144 кг, максимальное значение — 385,008668 кг.
  • Моды — 0,144144 и 93,165077 кг, их частота 5.
  • Медиана — 40,14 кг, среднее арифметическое — 189,48 кг.
  • Из-за малого числа значений форму распределения трудно охарактеризовать. Наблюдаются отдельные дискретно распределённые значения.
  • Половина всех значений лежит в диапазоне 95–276 кг.

Wire 4 — масса проволочного материала номер 4

  • Значения определены для 14 записей из 3081 — это 2 % всех значений.
  • Для 14 записей встречается 14 различных уникальных значений.
  • Минимальное значение — 24,148801 кг, максимальное значение — 385,008668 кг.
  • Моды нет. Все значения уникальные.
  • Медиана — 45,23 кг, среднее арифметическое — 57,44 кг.
  • Из-за малого числа значений форму распределения трудно охарактеризовать. Наблюдаются отдельные дискретно распределённые значения. Каждое значение встречается один раз.
  • Половина всех значений лежит в диапазоне 41–76 кг.
  • Практически все значения не превышают 98 кг.

Wire 5 — масса проволочного материала номер 5

  • Значения определены для 1 записи из 3081 — это менее 0,1 % всех значений.
  • Встречается только одно значение — 15,132 кг.

Wire 6 — масса проволочного материала номер 6

  • Значения определены для 73 записей из 3081 — это 2 % всех значений.
  • Для 73 записей встречается 69 различных уникальных значений.
  • Минимальное значение — 0,03432 кг, максимальное значение — 180,454575 кг.
  • Моды — 18,086641, 20,145842, 25,0536, 38,198162 кг, их частоты — 2.
  • Медиана — 42,08 кг, среднее арифметическое — 48,02 кг.
  • Из-за малого числа значений форму распределения трудно охарактеризовать. Наблюдаются отдельные дискретно распределённые значения.
  • Половина всех значений лежит в диапазоне 2–64 кг.
  • Практически все значения не превышают 100 кг.

Wire 7 — масса проволочного материала номер 7

  • Значения определены для 11 записей из 3081 — это 0,4 % всех значений.
  • Для 11 записей встречается 10 различных уникальных значений.
  • Минимальное значение — 0,234208 кг, максимальное значение — 32,847674 кг.
  • Мода — 12,354473 кг, её частота — 2.
  • Медиана — 9,02 кг, среднее арифметическое — 10,04 кг.
  • Из-за малого числа значений форму распределения трудно охарактеризовать. Наблюдаются отдельные дискретно распределённые значения.
  • Половина всех значений лежит в диапазоне 7–12 кг.
  • Практически все значения не превышают 16 кг.

Wire 8 — масса проволочного материала номер 8

  • Значения определены для 19 записей из 3081 — это 0,6 % всех значений.
  • Для 19 записей встречается 13 различных уникальных значений.
  • Минимальное значение — 45,076721 кг, максимальное значение — 102,762401 кг.
  • Мода — 46,187439 кг, её частота — 6.
  • Медиана — 46,28 кг, среднее арифметическое — 53,63 кг.
  • Из-за малого числа значений форму распределения трудно охарактеризовать. Наблюдаются отдельные дискретно распределённые значения.
  • Половина всех значений лежит в диапазоне 46–48 кг.
  • Практически все значения не превышают 49 кг.

Wire 9 — масса проволочного материала номер 9

  • Значения определены для 29 записей из 3081 — это 1 % всех значений.
  • Для 29 записей встречается 25 различных уникальных значений.
  • Минимальное значение — 4,6228 кг, максимальное значение — 90,053604 кг.
  • Мода — 30,066399 кг, её частота — 5.
  • Медиана — 30,07 кг, среднее арифметическое — 34,16 кг.
  • Из-за малого числа значений форму распределения трудно охарактеризовать. Наблюдаются отдельные дискретно распределённые значения.
  • Половина всех значений лежит в диапазоне 22–44 кг.
  • Практически все значения не превышают 62 кг.

Время подачи проволочных материалов¶

In [56]:
df = pd.DataFrame()

for i in range(1, 10):
    df = df.join(
        time(data_wire_time.loc[data_wire_time[f'Wire {i}'].notna(),
                                f'Wire {i}'], f'{i}'),
        how='right').rename_axis('Проволочный материал', axis=0)

df.T
Out[56]:
Проволочный материал кол-во значений кол-во уникальных первая запись последняя запись
1 3055 3055 2019-05-03 11:06:19 2019-09-06 17:10:06
2 1079 1079 2019-05-03 13:15:34 2019-09-06 07:35:40
3 63 63 2019-05-04 04:34:27 2019-09-02 07:14:44
4 14 14 2019-05-07 15:19:17 2019-08-13 03:16:45
5 1 1 2019-08-13 06:14:30 2019-08-13 06:14:30
6 73 73 2019-05-07 14:46:05 2019-08-18 19:10:56
7 11 11 2019-07-27 05:49:05 2019-08-13 10:25:22
8 19 19 2019-05-14 11:29:24 2019-08-16 08:56:23
9 29 29 2019-05-04 17:21:27 2019-09-03 12:55:23
In [57]:
df = pd.DataFrame()

for i in range(1, 10):
    df = df.join(
        day(data_wire_time.loc[data_wire_time[f'Wire {i}'].notna(),
                               f'Wire {i}'], f'{i}'),
        how='right').rename_axis('Проволочный материал', axis=0)

df.T
Out[57]:
Проволочный материал кол-во значений кол-во уникальных мода частота моды мин медиана макс размах межквартильный размах
1 3055 123 06.07.2019 35 03.05.2019 03.07.2019 06.09.2019 127 64
2 1079 116 11.08.2019 23 03.05.2019 04.07.2019 06.09.2019 126 64
3 63 22 27.07.2019 7 04.05.2019 21.07.2019 02.09.2019 122 62
4 14 5 27.07.2019 7 07.05.2019 27.07.2019 13.08.2019 98 6
5 1 1 13.08.2019 1 13.08.2019 13.08.2019 13.08.2019 1 0
6 73 11 08.05.2019 16 07.05.2019 28.07.2019 18.08.2019 104 96
7 11 3 27.07.2019 4 27.07.2019 12.08.2019 13.08.2019 18 16
8 19 4 14.05.2019 10 14.05.2019 14.05.2019 16.08.2019 94 93
9 29 8 09.08.2019 8 04.05.2019 11.06.2019 03.09.2019 122 60
  • Значения массы каждого проволочного материала определены не для всех записей. Но если определено значение вносимой массы, то каждая запись о вносимой массе сопровождается записью об отметке времени внесения.
  • Значения определены с точностью до 1 с.
  • Для каждого каждого проволочного материала все отметки времени являются уникальными.
  • Все наблюдения проводились в период 127 дней.
  • В наборе данных представлены сведения:
    • о 123 днях (максимум) — для проволочного материала номер 1,
    • о немного меньшем количестве дней — 116 — для материала номер 2,
    • о небольшом количестве дней — 11, 22 — для материалов 6, 3, соответственно,
    • о совсем маленьком количестве дней — 1, 3, 4, 5, 8 — для материалов 5, 7, 8, 4, 9, соответственно.
  • Сведения о проволочных материалах появляются в период с 3 мая по 27 июля 2019 года:
    • с 3 мая 2019 года — о материалах номер 1, 2,
    • с 4 мая 2019 года — о материалах номер 3, 9,
    • с 7 мая 2019 года — о материалах номер 4, 6,
    • с 14 мая 2019 года — о материале номер 8,
    • с 27 июля 2019 года — о материале номер 7.
  • Последняя запись о проволочных материалах появляется в период с 13 августа по 6 сентября 2019 года:
    • 13 августа 2019 года — о материалах 4, 5, 7,
    • 16 августа 2019 года — о материале 8,
    • 18 августа 2019 года — о материале 6,
    • 2 сентября 2019 года — о материале 3,
    • 3 сентября 2019 года — о материале 9,
    • 6 сентября 2019 года — о материалах 1, 2.
  • Сведения о проволочном материале номер 5 появляются единожды — 8 июля 2019 года.
  • В течение одного дня наибольшее число упоминаний о сыпучем материале изменяется от 1 до 35.

Данные о продувке сплава газом¶

Номер партии¶

In [58]:
lot(data_gas)
Out[58]:
Номер партии
кол-во значений 3239
кол-во уникальных 3239
мин. значение 1
макс. значение 3241
кол-во пропущенных 2
пропущенные партии [193, 259]
  • Значения определены для всех записей.
  • 3239 значений характеризуют 3239 выпущенных партий. Каждая партия характеризуется одной записью.
  • Номер первой выпущенной партии — 1, последней — 3241.
  • Не обо всех партиях в наборе данных присутствуют данные. Сведения о 2 выпущенных партиях отсутствуют.
  • Номера партий, о которых отсутствуют сведения, расположены произвольно. Характер их отсутствия не систематический.

Объём подаваемого газа¶

In [59]:
descriptive_statistics(data_gas['Газ 1'], 'Объём подаваемого газа, м$^3$')
Out[59]:
Объём подаваемого газа, м$^3$
кол-во значений 3239
кол-во уникальных 3239
мин. 0.008399
-1.5IQR -0.253973
25 % 7.04
мода [0.0083985291, 0.0166956024, 0.2630289536, 0.2...
медиана 9.84
среднее ариф. 11.0
75 % 13.77
+1.5IQR 19.926507
макс. 77.99504
размах 77.986641
межквартильный размах 6.726827
In [60]:
graph(data_gas['Газ 1'],
      'объёма подаваемого газа', 'Объём подаваемого газа, м$^3$')
  • Значения определены для всех записей.
  • Для 3239 записей встречается 3239 различных уникальных значений.
  • Минимальное значение — 0,008399 м$^3$, максимальное значение — 77,99504 м$^3$.
  • Медиана — 9,84 м$^3$, среднее арифметическое — 11 м$^3$.
  • Распределение унимодальное, несимметричное, с длинным "хвостом" справа.
  • Половина всех значений лежит в пределах от 7,04 до 13,77 м$^3$.
  • Практически все значения не превышают 19,93 м$^3$.

Результаты измерения температуры¶

Номер партии¶

In [61]:
lot(data_temp)
Out[61]:
Номер партии
кол-во значений 18092
кол-во уникальных 3216
мин. значение 1
макс. значение 3241
кол-во пропущенных 25
пропущенные партии [41, 42, 355, 382, 506, 529, 540, 607, 683, 71...
  • Значения определены для всех записей.
  • 18 092 значения характеризуют 3216 выпущенных партий. Одна партия может характеризоватся несколькими записями.
  • Номер первой выпущенной партии — 1, последней — 3241.
  • Не обо всех партиях в наборе данных присутствуют данные. Сведения о 25 выпущенных партиях отсутствуют.
  • Номера партий, о которых отсутствуют сведения, расположены произвольно. Характер их отсутствия не систематический.

Температура¶

In [62]:
descriptive_statistics(data_temp['Температура'], 'Температура, $^{\circ}$C')
Out[62]:
Температура, $^{\circ}$C
кол-во значений 14665
кол-во уникальных 173
мин. 1191.0
-1.5IQR 1561.5
25 % 1580.0
мода [1593.0]
медиана 1590.0
среднее ариф. 1590.72
75 % 1599.0
+1.5IQR 1618.5
макс. 1705.0
размах 514.0
межквартильный размах 19.0
In [63]:
graph(data_temp.loc[data_temp['Температура'].notna(), 'Температура'],
      'температуры', 'Температура, $^{\circ}$C')
  • Значения определены для 14 665 записей — это 93,7 % всех записей.
  • Для 3239 записей встречается 3239 различных уникальных значений.
  • Минимальное значение — 1191 $^{\circ}$C, максимальное значение — 1705 $^{\circ}$C.
  • Медиана — 1590 $^{\circ}$C, среднее арифметическое — 1591 $^{\circ}$C.
  • Распределение унимодальное, почти симметричное.
  • Половина всех значений лежит в пределах от 1580 до 1599 $^{\circ}$C.
  • Практически все значения лежат в пределах от 1562 до 1618 $^{\circ}$C.

Время замера¶

In [64]:
time(data_temp['Время замера'], 'Время замера')
Out[64]:
Время замера
кол-во значений 18092
кол-во уникальных 18092
первая запись 2019-05-03 11:02:04
последняя запись 2019-09-06 17:30:05
In [65]:
day(data_temp['Время замера'], 'Время замера')
Out[65]:
Время замера
кол-во значений 18092
кол-во уникальных 123
мода 06.06.2019
частота моды 201
мин 03.05.2019
медиана 03.07.2019
макс 06.09.2019
размах 127
межквартильный размах 64
  • Значения определены для всех записей.
  • Значения определены с точностью до 1 с.
  • Все отметки времени являются уникальными.
  • Всего в наборе данных представлены сведения о 123 днях.
  • Наблюдения проводились в период 127 дней.
  • Первое наблюдение выполнено 3 мая 2019 года, последнее — 6 сентября 2019 года.
  • Медианное значение — 3 июля 2019 года — приходится почти на середину периода.
  • Чаще всего измерения проводились 6 июня 2019 года; было зарегистрировано 201 показание.

Промежуточный вывод

  • Все данные собраны за период 127 дней: с 3 мая 2019 года по 6 сентября 2019 года.
  • В разных наборах данных содержатся сведения о разном количестве выпущенных партий стали. Это связано с тем, что в наборах данных отсутствуют данные о некоторых партиях, причём количество и перечень отсутствующих партий в разных наборах данных — разный. Возможно, это связано либо с подготовкой данных для анализа (и тогда сведения о пропущенных партиях были удалены сознательно), либо с потерей части данных при сохранении и копировании данных, либо эти партии были бракованы ещё на производстве, и сведения о них не сохранялись.
  • В связи с тем, что отсутствуют сведения о некоторых партиях, количество дней наблюдения меньше периода, за который сведения были собраны, и составляет не более 123 дней.
  • Номер первой зарегистрированной партии — 1, последней — 3241.
  • Наименьшее число партий — 3081 — упомянуто в наборе данных о проволочных материалах, наибольшее — 3239 — в наборе данных о продувке сплава газом.
  • Значения температуры распределены в диапазоне 1191–1705 $^{\circ}$C. Поскольку температура плавления стали не может быть меньше 1300 $^{\circ}$C, все значения меньше этой величины будем считать аномальными.
  • Средняя температура расплава в ковше-печи составляет (1590$\pm$30) $^{\circ}$C.
  • Значения активной мощности распределены в диапазоне 0,22–1,46 МВт. Медианное значение — 0,60 МВт.
  • Значения реактивной мощности распределены в диапазоне 0,15–1,27 МВт. Медианное значение — 0,44 МВт. В наборе данных встречаются отрицательные значения реактивной мощности. Очевидно, что это аномальные значения. Их появление может быть связано либо с ошибкой регистрации значения реактивной мощности (например, если произошёл обрыв электрической цепи средства измерения), либо аномальные значения могли появиться при сохранении и копировании данных.
  • Значения объёма пропускаемого через расплав инертного газа распределены в диапазоне 0,008–78 м$^3$. Медианное значение — 10,0 м$^3$. Большинство значений распределено в диапазоне 0,0–20,0 м$^3$.
  • Из 15 различных сыпучих материалов чаще всего добавляли материалы номер 12, 14, 15, реже номер 3, 4, 6.
  • Наименьшая масса сыпучего материала, вносимая за одну операцию, — 1 кг, наибольшая — 1849 кг. Медианные значения для всех материалов находятся в диапазоне 31–298 кг за операцию.
  • Из 9 различных проволочных материалов чаще всего добавляли материал номер 1, реже номер 2.
  • Наименьшая масса проволочного материала, вносимая за одну операцию, — 0,03 кг, наибольшая — 385 кг. Медианные значения для всех материалов находятся в диапазоне 9–235 кг за операцию.
  • Поскольку значения температуры сопровождаются отметками времени проведения измерения, а показания средств измерения времени не синхронизированы друг с другом, использовать сведения о времени измерения из других наборов данных для обучения алгоритмов не представляется возможным.

Предобработка данных¶

Обработка аномальных значений¶

Температура¶

Партии, для которых наблюдаются аномальные значения температуры (менее 1300 $^{\circ}$C):

In [66]:
data_temp.loc[data_temp['Температура'] < 1300, 'key'].tolist()
Out[66]:
[867, 1214, 1619, 2052, 2561]
In [67]:
data_temp.shape
Out[67]:
(18092, 3)

Удалим из набора данных о результатах измерения температуры сведения о партиях с аномальными значениями температуры.

In [68]:
for key in data_temp.loc[data_temp['Температура'] < 1300, 'key'].tolist():
    data_temp = data_temp.loc[~(data_temp['key'] == key)]

len(data_temp.loc[data_temp['Температура'] < 1300])
Out[68]:
0
In [69]:
data_temp.shape
Out[69]:
(18065, 3)

Реактивная мощность¶

Партии, для которых наблюдаются аномальные (неположительные) значения реактивной мощности:

In [70]:
data_arc.loc[data_arc['Реактивная мощность'] <= 0, 'key'].tolist()
Out[70]:
[2116]
In [71]:
data_arc.shape
Out[71]:
(14876, 5)

Удалим из набора данных о параметрах работы электродов сведения о партиях с аномальными значениями реактивной мощности.

In [72]:
for key in data_arc.loc[data_arc['Реактивная мощность'] <= 0, 'key'].tolist():
    data_arc = data_arc.loc[~(data_arc['key'] == key)]

len(data_arc.loc[data_arc['Реактивная мощность'] <= 0])
Out[72]:
0
In [73]:
data_arc.shape
Out[73]:
(14872, 5)

Обогащение данных¶

Полная мощность¶

Рассчитаем для каждой подачи напряжения на электроды значение полной мощности по формуле:

$Полная\ мощность = \sqrt{(Активная\ мощность)^2 + (Реактивная\ мощность)^2}$

In [74]:
data_arc['full_power'] = (data_arc['Активная мощность'] ** 2 +
                          data_arc['Реактивная мощность'] ** 2) ** 0.5
data_arc.head()
Out[74]:
key Начало нагрева дугой Конец нагрева дугой Активная мощность Реактивная мощность full_power
0 1 2019-05-03 11:02:14 2019-05-03 11:06:02 0.305130 0.211253 0.371123
1 1 2019-05-03 11:07:28 2019-05-03 11:10:33 0.765658 0.477438 0.902319
2 1 2019-05-03 11:11:44 2019-05-03 11:14:36 0.580313 0.430460 0.722536
3 1 2019-05-03 11:18:14 2019-05-03 11:24:19 0.518496 0.379979 0.642824
4 1 2019-05-03 11:26:09 2019-05-03 11:28:37 0.867133 0.643691 1.079934

Коэффициент мощности¶

Рассчитаем для каждой подачи напряжения на электроды значение коэффициента мощности по формуле:

$Коэффициент\ мощности = \frac{Активная\ мощность}{Полная\ мощность}$

In [75]:
data_arc['power_factor'] = data_arc['Активная мощность'] / data_arc['full_power']
data_arc.head()
Out[75]:
key Начало нагрева дугой Конец нагрева дугой Активная мощность Реактивная мощность full_power power_factor
0 1 2019-05-03 11:02:14 2019-05-03 11:06:02 0.305130 0.211253 0.371123 0.822181
1 1 2019-05-03 11:07:28 2019-05-03 11:10:33 0.765658 0.477438 0.902319 0.848545
2 1 2019-05-03 11:11:44 2019-05-03 11:14:36 0.580313 0.430460 0.722536 0.803161
3 1 2019-05-03 11:18:14 2019-05-03 11:24:19 0.518496 0.379979 0.642824 0.806591
4 1 2019-05-03 11:26:09 2019-05-03 11:28:37 0.867133 0.643691 1.079934 0.802950

Время подогрева¶

Рассчитаем время, в течение которого подавалась электроэнергия для подогрева расплава, по формуле:

$Время\ нагрева = Конец\ нагрева\ дугой - Начало\ нагрева\ дугой$

In [76]:
data_arc['heating_time'] = (pd.to_datetime(data_arc['Конец нагрева дугой']) -
                            pd.to_datetime(data_arc['Начало нагрева дугой'])
                            ).dt.total_seconds()
data_arc.head()
Out[76]:
key Начало нагрева дугой Конец нагрева дугой Активная мощность Реактивная мощность full_power power_factor heating_time
0 1 2019-05-03 11:02:14 2019-05-03 11:06:02 0.305130 0.211253 0.371123 0.822181 228.0
1 1 2019-05-03 11:07:28 2019-05-03 11:10:33 0.765658 0.477438 0.902319 0.848545 185.0
2 1 2019-05-03 11:11:44 2019-05-03 11:14:36 0.580313 0.430460 0.722536 0.803161 172.0
3 1 2019-05-03 11:18:14 2019-05-03 11:24:19 0.518496 0.379979 0.642824 0.806591 365.0
4 1 2019-05-03 11:26:09 2019-05-03 11:28:37 0.867133 0.643691 1.079934 0.802950 148.0

Потреблённая энергия¶

Рассчитаем, какое количество энергии (в МДж) потреблялось при каждом нагреве расплава, по формуле:

$Потреблённая\ энергия = Полная\ мощность \times Время\ нагрева$

In [77]:
data_arc['energy'] = data_arc['full_power'] * data_arc['heating_time']
data_arc.head()
Out[77]:
key Начало нагрева дугой Конец нагрева дугой Активная мощность Реактивная мощность full_power power_factor heating_time energy
0 1 2019-05-03 11:02:14 2019-05-03 11:06:02 0.305130 0.211253 0.371123 0.822181 228.0 84.616003
1 1 2019-05-03 11:07:28 2019-05-03 11:10:33 0.765658 0.477438 0.902319 0.848545 185.0 166.928978
2 1 2019-05-03 11:11:44 2019-05-03 11:14:36 0.580313 0.430460 0.722536 0.803161 172.0 124.276277
3 1 2019-05-03 11:18:14 2019-05-03 11:24:19 0.518496 0.379979 0.642824 0.806591 365.0 234.630603
4 1 2019-05-03 11:26:09 2019-05-03 11:28:37 0.867133 0.643691 1.079934 0.802950 148.0 159.830252

Сыпучие материалы¶

Приведём наименования признаков к "змеиному_регистру".

In [78]:
data_bulk = data_bulk.rename(
    columns=lambda column: re.sub(r'(?<!^)(?=[A-Z])| ', '_', column).lower())
data_bulk.columns
Out[78]:
Index(['key', 'bulk_1', 'bulk_2', 'bulk_3', 'bulk_4', 'bulk_5', 'bulk_6',
       'bulk_7', 'bulk_8', 'bulk_9', 'bulk_10', 'bulk_11', 'bulk_12',
       'bulk_13', 'bulk_14', 'bulk_15'],
      dtype='object')
In [79]:
data_bulk.shape
Out[79]:
(3129, 16)

Рассчитаем для каждой партии, сколько видов сыпучих материалов вносили в расплав.

In [80]:
data_bulk['bulk_sum'] = data_bulk.drop(['key'], axis=1).sum(axis=1)
data_bulk['bulk_count'] = data_bulk.drop(['key', 'bulk_sum'],
                                         axis=1).count(axis=1)
data_bulk.head()
Out[80]:
key bulk_1 bulk_2 bulk_3 bulk_4 bulk_5 bulk_6 bulk_7 bulk_8 bulk_9 bulk_10 bulk_11 bulk_12 bulk_13 bulk_14 bulk_15 bulk_sum bulk_count
0 1 NaN NaN NaN 43.0 NaN NaN NaN NaN NaN NaN NaN 206.0 NaN 150.0 154.0 553.0 4
1 2 NaN NaN NaN 73.0 NaN NaN NaN NaN NaN NaN NaN 206.0 NaN 149.0 154.0 582.0 4
2 3 NaN NaN NaN 34.0 NaN NaN NaN NaN NaN NaN NaN 205.0 NaN 152.0 153.0 544.0 4
3 4 NaN NaN NaN 81.0 NaN NaN NaN NaN NaN NaN NaN 207.0 NaN 153.0 154.0 595.0 4
4 5 NaN NaN NaN 78.0 NaN NaN NaN NaN NaN NaN NaN 203.0 NaN 151.0 152.0 584.0 4
In [81]:
data_bulk.shape
Out[81]:
(3129, 18)

Проволочные материалы¶

Приведём наименования признаков к "змеиному_регистру".

In [82]:
data_wire = data_wire.rename(
    columns=lambda column: re.sub(r'(?<!^)(?=[A-Z])| ', '_', column).lower())
data_wire.columns
Out[82]:
Index(['key', 'wire_1', 'wire_2', 'wire_3', 'wire_4', 'wire_5', 'wire_6',
       'wire_7', 'wire_8', 'wire_9'],
      dtype='object')
In [83]:
data_wire.shape
Out[83]:
(3081, 10)

Рассчитаем для каждой партии, сколько видов проволочных материалов вносили в расплав.

In [84]:
data_wire['wire_sum'] = data_wire.drop(['key'], axis=1).sum(axis=1)
data_wire['wire_count'] = data_wire.drop(['key', 'wire_sum'],
                                         axis=1).count(axis=1)
data_wire.head()
Out[84]:
key wire_1 wire_2 wire_3 wire_4 wire_5 wire_6 wire_7 wire_8 wire_9 wire_sum wire_count
0 1 60.059998 NaN NaN NaN NaN NaN NaN NaN NaN 60.059998 1
1 2 96.052315 NaN NaN NaN NaN NaN NaN NaN NaN 96.052315 1
2 3 91.160157 NaN NaN NaN NaN NaN NaN NaN NaN 91.160157 1
3 4 89.063515 NaN NaN NaN NaN NaN NaN NaN NaN 89.063515 1
4 5 89.238236 9.11456 NaN NaN NaN NaN NaN NaN NaN 98.352796 2
In [85]:
data_bulk.shape
Out[85]:
(3129, 18)

Обработка пропусков¶

Температура¶

Количество партий, для которых неизвестны некоторые результаты измерения температуры:

In [86]:
len(data_temp.loc[data_temp['Температура'].isna(), 'key'].unique())
Out[86]:
738
In [87]:
data_temp.shape
Out[87]:
(18065, 3)

Поскольку отсутствующие значения температуры могут свидетельствовать о неисправности средства измерения и, кроме того, последняя измеренная температура является целевым признаком, необходимо удалить недостаточно достоверные сведения о таких партиях.

In [88]:
for key in data_temp.loc[data_temp['Температура'].isna(), 'key'].unique():
    data_temp = data_temp.loc[~(data_temp['key'] == key)]

len(data_temp.loc[data_temp['Температура'].isna(), 'key'].unique())
Out[88]:
0
In [89]:
data_temp.shape
Out[89]:
(13905, 3)

Масса сыпучих материалов¶

Среди значений массы сыпучих материалов присутствуют пропуски, причиной которых является технологический процесс стадии легирования: не все сыпучие материалы используются для получения разных марок стали. Каждая марка стали требует своего набора добавок.

In [90]:
data_bulk.head()
Out[90]:
key bulk_1 bulk_2 bulk_3 bulk_4 bulk_5 bulk_6 bulk_7 bulk_8 bulk_9 bulk_10 bulk_11 bulk_12 bulk_13 bulk_14 bulk_15 bulk_sum bulk_count
0 1 NaN NaN NaN 43.0 NaN NaN NaN NaN NaN NaN NaN 206.0 NaN 150.0 154.0 553.0 4
1 2 NaN NaN NaN 73.0 NaN NaN NaN NaN NaN NaN NaN 206.0 NaN 149.0 154.0 582.0 4
2 3 NaN NaN NaN 34.0 NaN NaN NaN NaN NaN NaN NaN 205.0 NaN 152.0 153.0 544.0 4
3 4 NaN NaN NaN 81.0 NaN NaN NaN NaN NaN NaN NaN 207.0 NaN 153.0 154.0 595.0 4
4 5 NaN NaN NaN 78.0 NaN NaN NaN NaN NaN NaN NaN 203.0 NaN 151.0 152.0 584.0 4
In [91]:
data_bulk.isna().sum().sum()
Out[91]:
35776

Можно с уверенностью утверждать, что пропущенные значения необходимо заполнить нулём, поскольку компоненты с пропусками при производстве каждой партии в расплав не добавлялись.

In [92]:
data_bulk.fillna(0, inplace=True)
data_bulk.head()
Out[92]:
key bulk_1 bulk_2 bulk_3 bulk_4 bulk_5 bulk_6 bulk_7 bulk_8 bulk_9 bulk_10 bulk_11 bulk_12 bulk_13 bulk_14 bulk_15 bulk_sum bulk_count
0 1 0.0 0.0 0.0 43.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 206.0 0.0 150.0 154.0 553.0 4
1 2 0.0 0.0 0.0 73.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 206.0 0.0 149.0 154.0 582.0 4
2 3 0.0 0.0 0.0 34.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 205.0 0.0 152.0 153.0 544.0 4
3 4 0.0 0.0 0.0 81.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 207.0 0.0 153.0 154.0 595.0 4
4 5 0.0 0.0 0.0 78.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 203.0 0.0 151.0 152.0 584.0 4
In [93]:
data_bulk.isna().sum().sum()
Out[93]:
0

Масса проволочных материалов¶

Среди значений массы проволочных материалов также имеются пропуски. Аналогично, можно утверждать, что их появление связано с особенностями технологического процесса стадии легирования. Для производства каждой марки стали необходимо использовать разный набор проволочных материалов.

In [94]:
data_wire.head()
Out[94]:
key wire_1 wire_2 wire_3 wire_4 wire_5 wire_6 wire_7 wire_8 wire_9 wire_sum wire_count
0 1 60.059998 NaN NaN NaN NaN NaN NaN NaN NaN 60.059998 1
1 2 96.052315 NaN NaN NaN NaN NaN NaN NaN NaN 96.052315 1
2 3 91.160157 NaN NaN NaN NaN NaN NaN NaN NaN 91.160157 1
3 4 89.063515 NaN NaN NaN NaN NaN NaN NaN NaN 89.063515 1
4 5 89.238236 9.11456 NaN NaN NaN NaN NaN NaN NaN 98.352796 2
In [95]:
data_wire.isna().sum().sum()
Out[95]:
23385

Эти пропуски также необходимо заполнить нулём, как и в случае с сыпучими материалами, поскольку имеется высокая уверенность в том, что отсутствующие сведения говорят о неиспользовании материала в процессе легирования.

In [96]:
data_wire.fillna(0, inplace=True)
data_wire.head()
Out[96]:
key wire_1 wire_2 wire_3 wire_4 wire_5 wire_6 wire_7 wire_8 wire_9 wire_sum wire_count
0 1 60.059998 0.00000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 60.059998 1
1 2 96.052315 0.00000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 96.052315 1
2 3 91.160157 0.00000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 91.160157 1
3 4 89.063515 0.00000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 89.063515 1
4 5 89.238236 9.11456 0.0 0.0 0.0 0.0 0.0 0.0 0.0 98.352796 2
In [97]:
data_wire.isna().sum().sum()
Out[97]:
0

Формирование набора данных для обучения алгоритмов¶

Температура¶

Сведение всех данных будем производить, используя номер партии в качестве ключа для объединения.

Прежде всего сформируем набор данных из номеров партий и конечной температурой расплава — целевой переменной.

In [98]:
data = pd.DataFrame(data_temp.groupby('key')['key'].tail(1)).join(
    data_temp.groupby('key')['Температура'].tail(1)).rename(
    {'Температура': 'last_temperature'}, axis=1)
data.head()
Out[98]:
key last_temperature
5 1 1613.0
10 2 1602.0
16 3 1599.0
21 4 1625.0
26 5 1602.0
In [99]:
data.shape
Out[99]:
(2473, 2)

Теперь добавим к набору данных сведения о начальной температуре легирования.

In [100]:
data = data.merge(
    pd.DataFrame(data_temp.groupby('key')['key'].head(1)).join(
    data_temp.groupby('key')['Температура'].head(1)).rename(
    {'Температура': 'first_temperature'}, axis=1),
    on='key')
data.head()
Out[100]:
key last_temperature first_temperature
0 1 1613.0 1571.0
1 2 1602.0 1581.0
2 3 1599.0 1596.0
3 4 1625.0 1601.0
4 5 1602.0 1576.0
In [101]:
data.shape
Out[101]:
(2473, 3)

Время легирования¶

Время проведения процесса легирования — это время между первым измерением температуры и последним измерением.

In [102]:
time = pd.DataFrame(data_temp.groupby('key')['key'].tail(1)).join(
    pd.to_datetime(data_temp.groupby('key')['Время замера'].tail(1))).rename(
    {'Время замера': 'final_time'}, axis=1).merge(
    pd.DataFrame(data_temp.groupby('key')['key'].head(1)).join(
    pd.to_datetime(data_temp.groupby('key')['Время замера'].head(1))).rename(
    {'Время замера': 'initial_time'}, axis=1),
    on='key'
)
time.head()
Out[102]:
key final_time initial_time
0 1 2019-05-03 11:30:38 2019-05-03 11:02:04
1 2 2019-05-03 11:55:09 2019-05-03 11:34:04
2 3 2019-05-03 12:35:57 2019-05-03 12:06:44
3 4 2019-05-03 12:59:47 2019-05-03 12:39:27
4 5 2019-05-03 13:36:39 2019-05-03 13:11:03
In [103]:
time['process_time'] = (pd.to_datetime(time['final_time']) -
                        pd.to_datetime(time['initial_time'])
                        ).dt.total_seconds()
time.head()
Out[103]:
key final_time initial_time process_time
0 1 2019-05-03 11:30:38 2019-05-03 11:02:04 1714.0
1 2 2019-05-03 11:55:09 2019-05-03 11:34:04 1265.0
2 3 2019-05-03 12:35:57 2019-05-03 12:06:44 1753.0
3 4 2019-05-03 12:59:47 2019-05-03 12:39:27 1220.0
4 5 2019-05-03 13:36:39 2019-05-03 13:11:03 1536.0

Добавим сведения о времени проведения процесса легирования к набору данных.

In [104]:
data = data.merge(time[['key', 'process_time']], on='key')
data.head()
Out[104]:
key last_temperature first_temperature process_time
0 1 1613.0 1571.0 1714.0
1 2 1602.0 1581.0 1265.0
2 3 1599.0 1596.0 1753.0
3 4 1625.0 1601.0 1220.0
4 5 1602.0 1576.0 1536.0
In [105]:
data.shape
Out[105]:
(2473, 4)

Полная мощность¶

Добавим к набору данных сведения о суммарном значении полной мощности. Кроме того, поскольку для каждой партии, в общем случае, производилось несколько операций передачи электродами электроэнергии расплаву, то добавим к набору данных статистические сведения, рассчитанные для каждой партии: среднее арифметическое, минимум и максимум значений.

In [106]:
data = data.merge(
    data_arc.groupby('key')['full_power']
    .agg(['sum', 'mean', 'min', 'max']).reset_index()
    .rename(
        {'sum': 'full_power_sum',
         'mean': 'full_power_avg',
         'min': 'full_power_min',
         'max': 'full_power_max'}, axis=1),
    on='key')
data.head()
Out[106]:
key last_temperature first_temperature process_time full_power_sum full_power_avg full_power_min full_power_max
0 1 1613.0 1571.0 1714.0 3.718736 0.743747 0.371123 1.079934
1 2 1602.0 1581.0 1265.0 2.588349 0.647087 0.332731 0.955315
2 3 1599.0 1596.0 1753.0 5.019223 1.003845 0.502111 1.497189
3 4 1625.0 1601.0 1220.0 3.400038 0.850010 0.393685 1.097105
4 5 1602.0 1576.0 1536.0 2.816980 0.704245 0.428064 1.110873
In [107]:
data.shape
Out[107]:
(2470, 8)

Активная мощность¶

Поскольку активная мощность не является аддитивной величиной, то к набору данных можно добавить только статистические показатели: среднее арифметическое, минимум и максимум значений активной мощности.

In [108]:
data = data.merge(
    data_arc.groupby('key')['Активная мощность']
    .agg(['mean', 'min', 'max']).reset_index()
    .rename(
        {'mean': 'active_power_avg',
         'min': 'active_power_min',
         'max': 'active_power_max'}, axis=1),
    on='key')
data.head()
Out[108]:
key last_temperature first_temperature process_time full_power_sum full_power_avg full_power_min full_power_max active_power_avg active_power_min active_power_max
0 1 1613.0 1571.0 1714.0 3.718736 0.743747 0.371123 1.079934 0.607346 0.305130 0.867133
1 2 1602.0 1581.0 1265.0 2.588349 0.647087 0.332731 0.955315 0.534852 0.261665 0.786322
2 3 1599.0 1596.0 1753.0 5.019223 1.003845 0.502111 1.497189 0.812728 0.421693 1.222963
3 4 1625.0 1601.0 1220.0 3.400038 0.850010 0.393685 1.097105 0.676622 0.310693 0.887855
4 5 1602.0 1576.0 1536.0 2.816980 0.704245 0.428064 1.110873 0.563238 0.324563 0.892957
In [109]:
data.shape
Out[109]:
(2470, 11)

Реактивная мощность¶

Реактивная мощность, также как и активная, не является аддитивной величиной, поэтому и в этом случае к набору данных можно добавить только статистические показатели: среднее арифметическое, минимум и максимум значений реактивной мощности.

In [110]:
data = data.merge(
    data_arc.groupby('key')['Реактивная мощность']
    .agg(['mean', 'min', 'max']).reset_index()
    .rename(
        {'mean': 'reactive_power_avg',
         'min': 'reactive_power_min',
         'max': 'reactive_power_max'}, axis=1),
    on='key')
data.head()
Out[110]:
key last_temperature first_temperature process_time full_power_sum full_power_avg full_power_min full_power_max active_power_avg active_power_min active_power_max reactive_power_avg reactive_power_min reactive_power_max
0 1 1613.0 1571.0 1714.0 3.718736 0.743747 0.371123 1.079934 0.607346 0.305130 0.867133 0.428564 0.211253 0.643691
1 2 1602.0 1581.0 1265.0 2.588349 0.647087 0.332731 0.955315 0.534852 0.261665 0.786322 0.363339 0.205527 0.542517
2 3 1599.0 1596.0 1753.0 5.019223 1.003845 0.502111 1.497189 0.812728 0.421693 1.222963 0.587491 0.272562 0.863676
3 4 1625.0 1601.0 1220.0 3.400038 0.850010 0.393685 1.097105 0.676622 0.310693 0.887855 0.514248 0.241781 0.654661
4 5 1602.0 1576.0 1536.0 2.816980 0.704245 0.428064 1.110873 0.563238 0.324563 0.892957 0.421998 0.279102 0.660807
In [111]:
data.shape
Out[111]:
(2470, 14)

Коэффициент мощности¶

Коэффициент мощности прямо пропорционален активной мощности и также не является аддитивной величиной. Поэтому к набору данных можно добавить только статистические показатели: среднее арифметическое, минимум и максимум значений коэффициента мощности.

In [112]:
data = data.merge(
    data_arc.groupby('key')['power_factor']
    .agg(['mean', 'min', 'max']).reset_index()
    .rename(
        {'mean': 'power_factor_avg',
         'min': 'power_factor_min',
         'max': 'power_factor_max'}, axis=1),
    on='key')
data.head()
Out[112]:
key last_temperature first_temperature process_time full_power_sum full_power_avg full_power_min full_power_max active_power_avg active_power_min active_power_max reactive_power_avg reactive_power_min reactive_power_max power_factor_avg power_factor_min power_factor_max
0 1 1613.0 1571.0 1714.0 3.718736 0.743747 0.371123 1.079934 0.607346 0.305130 0.867133 0.428564 0.211253 0.643691 0.816686 0.802950 0.848545
1 2 1602.0 1581.0 1265.0 2.588349 0.647087 0.332731 0.955315 0.534852 0.261665 0.786322 0.363339 0.205527 0.542517 0.825276 0.786416 0.865721
2 3 1599.0 1596.0 1753.0 5.019223 1.003845 0.502111 1.497189 0.812728 0.421693 1.222963 0.587491 0.272562 0.863676 0.809724 0.752692 0.839841
3 4 1625.0 1601.0 1220.0 3.400038 0.850010 0.393685 1.097105 0.676622 0.310693 0.887855 0.514248 0.241781 0.654661 0.793923 0.779854 0.809271
4 5 1602.0 1576.0 1536.0 2.816980 0.704245 0.428064 1.110873 0.563238 0.324563 0.892957 0.421998 0.279102 0.660807 0.796818 0.758211 0.831286
In [113]:
data.shape
Out[113]:
(2470, 17)

Время подогрева¶

Время подогрева — это время, в течение которого на электроды подавалось напряжение, и они сообщали энергию расплаву. Можно рассчитать суммарное время передачи энергии электродами, а также статистические показатели: среднее арифметическое, минимум и максимум значений времени подогрева, и количество таких операций.

In [114]:
data = data.merge(
    data_arc.groupby('key')['heating_time']
    .agg(['sum', 'mean', 'min', 'max', 'count']).reset_index()
    .rename(
        {'sum': 'heating_time_sum',
         'mean': 'heating_time_avg',
         'min': 'heating_time_min',
         'max': 'heating_time_max',
         'count': 'heating_count'}, axis=1),
    on='key')
data.head()
Out[114]:
key last_temperature first_temperature process_time full_power_sum full_power_avg full_power_min full_power_max active_power_avg active_power_min active_power_max reactive_power_avg reactive_power_min reactive_power_max power_factor_avg power_factor_min power_factor_max heating_time_sum heating_time_avg heating_time_min heating_time_max heating_count
0 1 1613.0 1571.0 1714.0 3.718736 0.743747 0.371123 1.079934 0.607346 0.305130 0.867133 0.428564 0.211253 0.643691 0.816686 0.802950 0.848545 1098.0 219.60 148.0 365.0 5
1 2 1602.0 1581.0 1265.0 2.588349 0.647087 0.332731 0.955315 0.534852 0.261665 0.786322 0.363339 0.205527 0.542517 0.825276 0.786416 0.865721 811.0 202.75 126.0 338.0 4
2 3 1599.0 1596.0 1753.0 5.019223 1.003845 0.502111 1.497189 0.812728 0.421693 1.222963 0.587491 0.272562 0.863676 0.809724 0.752692 0.839841 655.0 131.00 65.0 280.0 5
3 4 1625.0 1601.0 1220.0 3.400038 0.850010 0.393685 1.097105 0.676622 0.310693 0.887855 0.514248 0.241781 0.654661 0.793923 0.779854 0.809271 741.0 185.25 99.0 278.0 4
4 5 1602.0 1576.0 1536.0 2.816980 0.704245 0.428064 1.110873 0.563238 0.324563 0.892957 0.421998 0.279102 0.660807 0.796818 0.758211 0.831286 869.0 217.25 71.0 415.0 4
In [115]:
data.shape
Out[115]:
(2470, 22)

Потреблённая энергия¶

Для энергии также допустимо рассчитывать сумму значений энергии, сообщённой электродами расплаву на каждой операции подогрева. Кроме того, можно рассчитать статистические показатели: среднее арифметическое, минимум и максимум значений потреблённой энергии.

In [116]:
data = data.merge(
    data_arc.groupby('key')['energy']
    .agg(['sum', 'mean', 'min', 'max']).reset_index()
    .rename(
        {'sum': 'energy_sum',
         'mean': 'energy_avg',
         'min': 'energy_min',
         'max': 'energy_max'}, axis=1),
    on='key')
data.head()
Out[116]:
key last_temperature first_temperature process_time full_power_sum full_power_avg full_power_min full_power_max active_power_avg active_power_min active_power_max reactive_power_avg reactive_power_min reactive_power_max power_factor_avg power_factor_min power_factor_max heating_time_sum heating_time_avg heating_time_min heating_time_max heating_count energy_sum energy_avg energy_min energy_max
0 1 1613.0 1571.0 1714.0 3.718736 0.743747 0.371123 1.079934 0.607346 0.305130 0.867133 0.428564 0.211253 0.643691 0.816686 0.802950 0.848545 1098.0 219.60 148.0 365.0 5 770.282114 154.056423 84.616003 234.630603
1 2 1602.0 1581.0 1265.0 2.588349 0.647087 0.332731 0.955315 0.534852 0.261665 0.786322 0.363339 0.205527 0.542517 0.825276 0.786416 0.865721 811.0 202.75 126.0 338.0 4 481.760005 120.440001 60.312695 200.616176
2 3 1599.0 1596.0 1753.0 5.019223 1.003845 0.502111 1.497189 0.812728 0.421693 1.222963 0.587491 0.272562 0.863676 0.809724 0.752692 0.839841 655.0 131.00 65.0 280.0 5 722.837668 144.567534 32.637187 384.681584
3 4 1625.0 1601.0 1220.0 3.400038 0.850010 0.393685 1.097105 0.676622 0.310693 0.887855 0.514248 0.241781 0.654661 0.793923 0.779854 0.809271 741.0 185.25 99.0 278.0 4 683.455597 170.863899 38.974854 301.575212
4 5 1602.0 1576.0 1536.0 2.816980 0.704245 0.428064 1.110873 0.563238 0.324563 0.892957 0.421998 0.279102 0.660807 0.796818 0.758211 0.831286 869.0 217.25 71.0 415.0 4 512.169934 128.042484 78.871960 230.452869
In [117]:
data.shape
Out[117]:
(2470, 26)

Объём инертного газа¶

Добавим к набору данных сведения об объёме пропущенного через расплав инертного газа.

In [118]:
data = data.merge(data_gas, on='key').rename({'Газ 1': 'gas'}, axis=1)
data.head()
Out[118]:
key last_temperature first_temperature process_time full_power_sum full_power_avg full_power_min full_power_max active_power_avg active_power_min active_power_max reactive_power_avg reactive_power_min reactive_power_max power_factor_avg power_factor_min power_factor_max heating_time_sum heating_time_avg heating_time_min heating_time_max heating_count energy_sum energy_avg energy_min energy_max gas
0 1 1613.0 1571.0 1714.0 3.718736 0.743747 0.371123 1.079934 0.607346 0.305130 0.867133 0.428564 0.211253 0.643691 0.816686 0.802950 0.848545 1098.0 219.60 148.0 365.0 5 770.282114 154.056423 84.616003 234.630603 29.749986
1 2 1602.0 1581.0 1265.0 2.588349 0.647087 0.332731 0.955315 0.534852 0.261665 0.786322 0.363339 0.205527 0.542517 0.825276 0.786416 0.865721 811.0 202.75 126.0 338.0 4 481.760005 120.440001 60.312695 200.616176 12.555561
2 3 1599.0 1596.0 1753.0 5.019223 1.003845 0.502111 1.497189 0.812728 0.421693 1.222963 0.587491 0.272562 0.863676 0.809724 0.752692 0.839841 655.0 131.00 65.0 280.0 5 722.837668 144.567534 32.637187 384.681584 28.554793
3 4 1625.0 1601.0 1220.0 3.400038 0.850010 0.393685 1.097105 0.676622 0.310693 0.887855 0.514248 0.241781 0.654661 0.793923 0.779854 0.809271 741.0 185.25 99.0 278.0 4 683.455597 170.863899 38.974854 301.575212 18.841219
4 5 1602.0 1576.0 1536.0 2.816980 0.704245 0.428064 1.110873 0.563238 0.324563 0.892957 0.421998 0.279102 0.660807 0.796818 0.758211 0.831286 869.0 217.25 71.0 415.0 4 512.169934 128.042484 78.871960 230.452869 5.413692
In [119]:
data.shape
Out[119]:
(2468, 27)

Легирующие добавки¶

Добавим к набору данных сведения о массе каждого из добавленных сыпучих материалов, общей массе сыпучих материалов и о количестве их различных видов.

In [120]:
data = data.merge(data_bulk, on='key')
data.head()
Out[120]:
key last_temperature first_temperature process_time full_power_sum full_power_avg full_power_min full_power_max active_power_avg active_power_min active_power_max reactive_power_avg reactive_power_min reactive_power_max power_factor_avg power_factor_min power_factor_max heating_time_sum heating_time_avg heating_time_min heating_time_max heating_count energy_sum energy_avg energy_min energy_max gas bulk_1 bulk_2 bulk_3 bulk_4 bulk_5 bulk_6 bulk_7 bulk_8 bulk_9 bulk_10 bulk_11 bulk_12 bulk_13 bulk_14 bulk_15 bulk_sum bulk_count
0 1 1613.0 1571.0 1714.0 3.718736 0.743747 0.371123 1.079934 0.607346 0.305130 0.867133 0.428564 0.211253 0.643691 0.816686 0.802950 0.848545 1098.0 219.60 148.0 365.0 5 770.282114 154.056423 84.616003 234.630603 29.749986 0.0 0.0 0.0 43.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 206.0 0.0 150.0 154.0 553.0 4
1 2 1602.0 1581.0 1265.0 2.588349 0.647087 0.332731 0.955315 0.534852 0.261665 0.786322 0.363339 0.205527 0.542517 0.825276 0.786416 0.865721 811.0 202.75 126.0 338.0 4 481.760005 120.440001 60.312695 200.616176 12.555561 0.0 0.0 0.0 73.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 206.0 0.0 149.0 154.0 582.0 4
2 3 1599.0 1596.0 1753.0 5.019223 1.003845 0.502111 1.497189 0.812728 0.421693 1.222963 0.587491 0.272562 0.863676 0.809724 0.752692 0.839841 655.0 131.00 65.0 280.0 5 722.837668 144.567534 32.637187 384.681584 28.554793 0.0 0.0 0.0 34.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 205.0 0.0 152.0 153.0 544.0 4
3 4 1625.0 1601.0 1220.0 3.400038 0.850010 0.393685 1.097105 0.676622 0.310693 0.887855 0.514248 0.241781 0.654661 0.793923 0.779854 0.809271 741.0 185.25 99.0 278.0 4 683.455597 170.863899 38.974854 301.575212 18.841219 0.0 0.0 0.0 81.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 207.0 0.0 153.0 154.0 595.0 4
4 5 1602.0 1576.0 1536.0 2.816980 0.704245 0.428064 1.110873 0.563238 0.324563 0.892957 0.421998 0.279102 0.660807 0.796818 0.758211 0.831286 869.0 217.25 71.0 415.0 4 512.169934 128.042484 78.871960 230.452869 5.413692 0.0 0.0 0.0 78.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 203.0 0.0 151.0 152.0 584.0 4
In [121]:
data.shape
Out[121]:
(2400, 44)

Также добавим к набору данных сведения о массе проволочных материалов, общей добавленной массе и о количестве их различных видов.

In [122]:
data = data.merge(data_wire, on='key')
data.head()
Out[122]:
key last_temperature first_temperature process_time full_power_sum full_power_avg full_power_min full_power_max active_power_avg active_power_min active_power_max reactive_power_avg reactive_power_min reactive_power_max power_factor_avg power_factor_min power_factor_max heating_time_sum heating_time_avg heating_time_min heating_time_max heating_count energy_sum energy_avg energy_min energy_max gas bulk_1 bulk_2 bulk_3 bulk_4 bulk_5 bulk_6 bulk_7 bulk_8 bulk_9 bulk_10 bulk_11 bulk_12 bulk_13 bulk_14 bulk_15 bulk_sum bulk_count wire_1 wire_2 wire_3 wire_4 wire_5 wire_6 wire_7 wire_8 wire_9 wire_sum wire_count
0 1 1613.0 1571.0 1714.0 3.718736 0.743747 0.371123 1.079934 0.607346 0.305130 0.867133 0.428564 0.211253 0.643691 0.816686 0.802950 0.848545 1098.0 219.60 148.0 365.0 5 770.282114 154.056423 84.616003 234.630603 29.749986 0.0 0.0 0.0 43.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 206.0 0.0 150.0 154.0 553.0 4 60.059998 0.00000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 60.059998 1
1 2 1602.0 1581.0 1265.0 2.588349 0.647087 0.332731 0.955315 0.534852 0.261665 0.786322 0.363339 0.205527 0.542517 0.825276 0.786416 0.865721 811.0 202.75 126.0 338.0 4 481.760005 120.440001 60.312695 200.616176 12.555561 0.0 0.0 0.0 73.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 206.0 0.0 149.0 154.0 582.0 4 96.052315 0.00000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 96.052315 1
2 3 1599.0 1596.0 1753.0 5.019223 1.003845 0.502111 1.497189 0.812728 0.421693 1.222963 0.587491 0.272562 0.863676 0.809724 0.752692 0.839841 655.0 131.00 65.0 280.0 5 722.837668 144.567534 32.637187 384.681584 28.554793 0.0 0.0 0.0 34.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 205.0 0.0 152.0 153.0 544.0 4 91.160157 0.00000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 91.160157 1
3 4 1625.0 1601.0 1220.0 3.400038 0.850010 0.393685 1.097105 0.676622 0.310693 0.887855 0.514248 0.241781 0.654661 0.793923 0.779854 0.809271 741.0 185.25 99.0 278.0 4 683.455597 170.863899 38.974854 301.575212 18.841219 0.0 0.0 0.0 81.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 207.0 0.0 153.0 154.0 595.0 4 89.063515 0.00000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 89.063515 1
4 5 1602.0 1576.0 1536.0 2.816980 0.704245 0.428064 1.110873 0.563238 0.324563 0.892957 0.421998 0.279102 0.660807 0.796818 0.758211 0.831286 869.0 217.25 71.0 415.0 4 512.169934 128.042484 78.871960 230.452869 5.413692 0.0 0.0 0.0 78.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 203.0 0.0 151.0 152.0 584.0 4 89.238236 9.11456 0.0 0.0 0.0 0.0 0.0 0.0 0.0 98.352796 2
In [123]:
data.shape
Out[123]:
(2324, 55)

Обзор набора данных для обучения алгоритмов¶

In [124]:
df_info(data)
key last_temperature first_temperature process_time full_power_sum full_power_avg full_power_min full_power_max active_power_avg active_power_min active_power_max reactive_power_avg reactive_power_min reactive_power_max power_factor_avg power_factor_min power_factor_max heating_time_sum heating_time_avg heating_time_min heating_time_max heating_count energy_sum energy_avg energy_min energy_max gas bulk_1 bulk_2 bulk_3 bulk_4 bulk_5 bulk_6 bulk_7 bulk_8 bulk_9 bulk_10 bulk_11 bulk_12 bulk_13 bulk_14 bulk_15 bulk_sum bulk_count wire_1 wire_2 wire_3 wire_4 wire_5 wire_6 wire_7 wire_8 wire_9 wire_sum wire_count
0 1 1613.0 1571.0 1714.0 3.718736 0.743747 0.371123 1.079934 0.607346 0.305130 0.867133 0.428564 0.211253 0.643691 0.816686 0.802950 0.848545 1098.0 219.60 148.0 365.0 5 770.282114 154.056423 84.616003 234.630603 29.749986 0.0 0.0 0.0 43.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 206.0 0.0 150.0 154.0 553.0 4 60.059998 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 60.059998 1
1 2 1602.0 1581.0 1265.0 2.588349 0.647087 0.332731 0.955315 0.534852 0.261665 0.786322 0.363339 0.205527 0.542517 0.825276 0.786416 0.865721 811.0 202.75 126.0 338.0 4 481.760005 120.440001 60.312695 200.616176 12.555561 0.0 0.0 0.0 73.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 206.0 0.0 149.0 154.0 582.0 4 96.052315 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 96.052315 1
key last_temperature first_temperature process_time full_power_sum full_power_avg full_power_min full_power_max active_power_avg active_power_min active_power_max reactive_power_avg reactive_power_min reactive_power_max power_factor_avg power_factor_min power_factor_max heating_time_sum heating_time_avg heating_time_min heating_time_max heating_count energy_sum energy_avg energy_min energy_max gas bulk_1 bulk_2 bulk_3 bulk_4 bulk_5 bulk_6 bulk_7 bulk_8 bulk_9 bulk_10 bulk_11 bulk_12 bulk_13 bulk_14 bulk_15 bulk_sum bulk_count wire_1 wire_2 wire_3 wire_4 wire_5 wire_6 wire_7 wire_8 wire_9 wire_sum wire_count
2322 2498 1594.0 1591.0 1520.0 3.909917 0.781983 0.512900 1.190819 0.640462 0.419017 0.999939 0.447964 0.289814 0.646662 0.819245 0.793073 0.839707 750.0 150.00 41.0 256.0 5 581.810739 116.362148 25.647067 203.935064 14.953657 0.0 0.0 90.0 0.0 0.0 0.0 0.0 0.0 0.0 101.0 0.0 206.0 0.0 129.0 207.0 733.0 5 118.110717 0.00000 0.0 0.0 0.0 0.0 0.0 0.0 0.0 118.110717 1
2323 2499 1603.0 1569.0 1537.0 2.169252 0.542313 0.374585 0.881433 0.434271 0.296379 0.700677 0.324209 0.229071 0.534767 0.800782 0.777820 0.839161 883.0 220.75 71.0 312.0 4 532.386183 133.096546 26.595546 275.007073 11.336151 0.0 0.0 47.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 233.0 0.0 126.0 227.0 633.0 4 110.160958 50.00528 0.0 0.0 0.0 0.0 0.0 0.0 0.0 160.166238 2
Размер набора данных: (2324, 55)

Количество элементов данных: 127820

Количество дубликатов в наименованиях признаков: 0

Уникальные наименования признаков:
 ['active_power_avg', 'active_power_max', 'active_power_min', 'bulk_1', 'bulk_10', 'bulk_11', 'bulk_12', 'bulk_13', 'bulk_14', 'bulk_15', 'bulk_2', 'bulk_3', 'bulk_4', 'bulk_5', 'bulk_6', 'bulk_7', 'bulk_8', 'bulk_9', 'bulk_count', 'bulk_sum', 'energy_avg', 'energy_max', 'energy_min', 'energy_sum', 'first_temperature', 'full_power_avg', 'full_power_max', 'full_power_min', 'full_power_sum', 'gas', 'heating_count', 'heating_time_avg', 'heating_time_max', 'heating_time_min', 'heating_time_sum', 'key', 'last_temperature', 'power_factor_avg', 'power_factor_max', 'power_factor_min', 'process_time', 'reactive_power_avg', 'reactive_power_max', 'reactive_power_min', 'wire_1', 'wire_2', 'wire_3', 'wire_4', 'wire_5', 'wire_6', 'wire_7', 'wire_8', 'wire_9', 'wire_count', 'wire_sum']

Количество пропущенных значений: 0

Процент пропущенных значений: 0.0 %

Типы данных набора данных:
float64    51
int64       4
dtype: int64
  • Согласование данных

Проверим, согласуются ли записи в признаках process_time и heating_time_sum. Время проведения процесса легирования не должно быть меньше времени подогрева расплава.

In [125]:
sum(data['process_time'] <= data['heating_time_sum'])
Out[125]:
0
  • Проверка на дубликаты

Проверим количество полных дублей. Неявные дубликаты в наборе данных присутствовать не могут априори, поскольку каждая запись характеризует отдельную партию, и сбор исходных данных был распределён во времени.

In [126]:
data.duplicated().sum()
Out[126]:
0

Данные о партиях

  • Набор данных содержит 55 уникальных признаков и 2324 записи.
  • В наборе данных: 127 820 элементов данных.
  • Набор данных содержит данные следующего типа:
    • целочисленный — 4 признака,
    • вещественный — 51 признак.
  • Все признаки содержат значения (не являются пустыми).
  • Все признаки не содержат пропущенные значения.
  • Значения признаков согласованы друг с другом.
  • Дубликаты отсутствуют.

Исследовательский анализ данных¶

Описательный анализ¶

Температура¶

In [127]:
descriptive_statistics(
    data['first_temperature'], 'Начальная температура, \u2103').join(
descriptive_statistics(
    data['last_temperature'], 'Конечная температура, \u2103'))
Out[127]:
Начальная температура, ℃ Конечная температура, ℃
кол-во значений 2324 2324
кол-во уникальных 133 75
мин. 1519.0 1541.0
-1.5IQR 1539.0 1576.5
25 % 1571.0 1587.0
мода [1588.0] [1593.0]
медиана 1587.0 1593.0
среднее ариф. 1587.37 1593.37
75 % 1603.0 1598.0
+1.5IQR 1635.0 1609.5
макс. 1660.0 1653.0
размах 141.0 112.0
межквартильный размах 32.0 11.0
In [128]:
label = ['Конечная температура', 'Начальная температура']

plt.figure(figsize=(10, 3))
plt.title('График ядерной оценки плотности распределения')
sns.kdeplot(data['last_temperature'], color='coral')
sns.kdeplot(data['first_temperature'], color='gold', shade=True)
plt.xlabel('Температура, \u2103')
plt.ylabel('Плотность распределения')
plt.legend(label)
plt.show()

last_temperature — конечная температура ($^{\circ}$C)
Признак является количественным, непрерывным.
Шкала измерения признака: интервальная шкала.

  • Для 2324 записей встречается 75 различных уникальных значений.
  • Минимальное значение — 1541 $^{\circ}$C, максимальное значение — 1653 $^{\circ}$C.
  • Мода — 1593 $^{\circ}$C, медиана — 1593 $^{\circ}$C, среднее арифметическое — 1593 $^{\circ}$C.
  • На графике ядерной оценки плотности наблюдается отчётливый максимум при температуре 1593 $^{\circ}$C, кроме того, небольшой максимум при температуре 1620 $^{\circ}$C и плечо при 1575 $^{\circ}$C.
  • Основной пик имеет узкую форму: половина всех значений лежит в узком диапазоне от 1587 до 1598 $^{\circ}$C.
  • Значения распределены в нешироком диапазоне: практически все значения лежат в пределах от 1577 до 1609 $^{\circ}$C.

first_temperature — начальная температура ($^{\circ}$C)
Признак является количественным, непрерывным.
Шкала измерения признака: интервальная шкала.

  • Для 2324 записей встречается 133 различных уникальных значений.
  • Минимальное значение — 1519 $^{\circ}$C, максимальное значение — 1660 $^{\circ}$C.
  • Мода — 1588 $^{\circ}$C, медиана — 1587 $^{\circ}$C, среднее арифметическое — 1587 $^{\circ}$C.
  • На графике ядерной оценки плотности наблюдается широкий пик с максимумом при 1587 $^{\circ}$C, а также небольшое плечо при температуре 1575 $^{\circ}$C.
  • Значения распределены в широком диапазоне: половина всех значений лежит в диапазоне от 1571 до 1603 $^{\circ}$C вокруг среднего значения, и практически все значения лежат в пределах от 1539 до 1635 $^{\circ}$C.

Время легирования¶

In [129]:
descriptive_statistics(data['process_time'], 'Время легирования, с')
Out[129]:
Время легирования, с
кол-во значений 2324
кол-во уникальных 1630
мин. 339.0
-1.5IQR 227.0
25 % 1580.5
мода [1598.0, 1603.0]
медиана 2046.5
среднее ариф. 2323.68
75 % 2793.5
+1.5IQR 3866.0
макс. 23674.0
размах 23335.0
межквартильный размах 1213.0
In [130]:
plt.figure(figsize=(10, 3))
plt.title('График ядерной оценки плотности распределения')
sns.kdeplot(data['process_time'], color='gold', shade=True)
plt.xlabel('Время легирования, с')
plt.ylabel('Плотность распределения')
plt.show()

process_time — время легирования (с)
Признак является количественным, непрерывным.
Шкала измерения признака: интервальная шкала.

  • Для 2324 записей встречается 1630 различных уникальных значений.
  • Минимальное значение — 339 с (5,7 мин), максимальное значение — 23 674 с (6,6 ч).
  • Моды — 1598 и 1603 с (26,6–26,7 мин), медиана — 2047 с (34,1 мин), среднее арифметическое — 2324 с (38,7 мин).
  • На графике ядерной оценки плотности наблюдается отчётливый максимум при времени 1800 с (30 мин), кроме того, наблюдается небольшое плечо справа при времени 3600 с (60 мин) и длинный тонкий "хвост" справа.
  • Основной пик имеет узкую форму: половина всех значений лежит в узком диапазоне от 1581 до 2793 с (26–46 мин).
  • Значения распределены практически симметрично, почти все значения не превышают 3866 с (64 мин).

Полная мощность¶

In [131]:
descriptive_statistics(data['full_power_sum'], 'Полная мощность, МВт')
Out[131]:
Полная мощность, МВт
кол-во значений 2324
кол-во уникальных 2324
мин. 0.331897
-1.5IQR 0.886293
25 % 2.85
мода [0.3318973771514322, 0.42767528909208674, 0.50...
медиана 3.77
среднее ариф. 3.89
75 % 4.77
+1.5IQR 6.654875
макс. 15.288271
размах 14.956374
межквартильный размах 1.922861
In [132]:
plt.figure(figsize=(10, 3))
plt.title('График ядерной оценки плотности распределения')
sns.kdeplot(data['full_power_sum'], color='gold', shade=True)
plt.xlabel('Полная мощность (на стадию легирования), МВт')
plt.ylabel('Плотность распределения')
plt.show()

full_power_sum — суммарное значение полной мощности (МВт)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

  • Все значения являются уникальными.
  • Минимальное значение — 0,33 МВт, максимальное значение — 15,29 МВт.
  • Медиана — 3,77 МВт, среднее арифметическое — 3,89 МВт.
  • На графике ядерной оценки плотности наблюдается один максимум при мощности 3 МВт.
  • Значения распределены практически симметрично, половина всех значений лежит в диапазоне от 2,85 до 4,77 МВт. Наблюдаются небольшие плечи справа от максимума.
  • Практически все значения лежат в пределах от 0,89 до 6,65 МВт. У распределения наблюдается "хвост" справа.
In [133]:
col_name = 'Полная мощность, развиваемая за одну операцию подогрева, МВт'
pd.DataFrame(descriptive_statistics(
    data['full_power_min'], 'Минимальное значение').join(
descriptive_statistics(
    data['full_power_avg'], 'Среднее значение')).join(
descriptive_statistics(
    data['full_power_max'], 'Максимальное значение'))
).rename_axis(col_name, axis=1)
Out[133]:
Полная мощность, развиваемая за одну операцию подогрева, МВт Минимальное значение Среднее значение Максимальное значение
кол-во значений 2324 2324 2324
кол-во уникальных 2324 2324 2324
мин. 0.275718 0.331897 0.331897
-1.5IQR 0.233768 0.507749 0.540493
25 % 0.41 0.71 0.99
мода [0.2757183411255044, 0.2836848387154308, 0.285... [0.3318973771514322, 0.3813739286828069, 0.399... [0.3318973771514322, 0.40681076007033046, 0.42...
медиана 0.5 0.82 1.21
среднее ариф. 0.52 0.83 1.21
75 % 0.6 0.92 1.44
+1.5IQR 0.774966 1.128855 1.872782
макс. 1.429109 1.572238 1.898158
размах 1.153391 1.240341 1.566261
межквартильный размах 0.180399 0.207035 0.444097
In [134]:
label = ['Минимальное значение', 'Среднее значение', 'Максимальное значение']

plt.figure(figsize=(10, 3))
plt.title('График ядерной оценки плотности распределения')
sns.kdeplot(data['full_power_min'], color='coral')
sns.kdeplot(data['full_power_avg'], color='gold', shade=True)
sns.kdeplot(data['full_power_max'], color='sienna')
plt.xlabel('Полная мощность (на операцию подогрева), МВт')
plt.ylabel('Плотность распределения')
plt.legend(label)
plt.show()

full_power_min — минимальное значение полной мощности для одной операции подогрева расплава (МВт)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

  • Минимальные значения полной мощности для одной операции подогрева расплава распределены в диапазоне от 0,28 до 1,43 МВт. Обычно минимальная развиваемая полная мощность составляет 0,5 МВт за одну операцию.

full_power_avg — среднее значение полной мощности для одной операции подогрева расплава (МВт)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

  • Средние значения полной мощности для одной операции подогрева расплава распределены в диапазоне от 0,33 до 1,57 МВт. Обычно средняя развиваемая полная мощность составляет 0,8 МВт за одну операцию.

full_power_max — максимальное значение полной мощности для одной операции подогрева расплава (МВт)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

  • Максимальные значения полной мощности для одной операции подогрева расплава распределены в диапазоне от 0,33 до 1,90 МВт. Обычно максимальная развиваемая полная мощность составляет 1,2 МВт за одну операцию.

Активная мощность¶

In [135]:
col_name = 'Активная мощность, развиваемая за одну операцию подогрева, МВт'
pd.DataFrame(descriptive_statistics(
    data['active_power_min'], 'Минимальное значение').join(
descriptive_statistics(
    data['active_power_avg'], 'Среднее значение')).join(
descriptive_statistics(
    data['active_power_max'], 'Максимальное значение'))
    ).rename_axis(col_name, axis=1)
Out[135]:
Активная мощность, развиваемая за одну операцию подогрева, МВт Минимальное значение Среднее значение Максимальное значение
кол-во значений 2324 2324 2324
кол-во уникальных 2253 2323 2264
мин. 0.223895 0.267676 0.267676
-1.5IQR 0.188311 0.407249 0.43934
25 % 0.33 0.58 0.8
мода [0.304755] [0.557008] [0.603421, 0.617319, 0.67913, 0.7157, 0.750905...
медиана 0.41 0.66 0.97
среднее ариф. 0.42 0.66 0.97
75 % 0.48 0.74 1.16
+1.5IQR 0.62552 0.90442 1.504835
макс. 1.140738 1.243889 1.463773
размах 0.916843 0.976213 1.196097
межквартильный размах 0.145736 0.165724 0.355165
In [136]:
label = ['Минимальное значение', 'Среднее значение', 'Максимальное значение']

plt.figure(figsize=(10, 3))
plt.title('График ядерной оценки плотности распределения')
sns.kdeplot(data['active_power_min'], color='coral')
sns.kdeplot(data['active_power_avg'], color='gold', shade=True)
sns.kdeplot(data['active_power_max'], color='sienna')
plt.xlabel('Активная мощность (на операцию подогрева), МВт')
plt.ylabel('Плотность распределения')
plt.legend(label)
plt.show()

active_power_min — минимальное значение активной мощности для одной операции подогрева расплава (МВт)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

  • Минимальные значения активной мощности для одной операции подогрева расплава распределены в диапазоне от 0,22 до 1,14 МВт. Обычно минимальная развиваемая активная мощность составляет 0,4 МВт за одну операцию.

active_power_avg — среднее значение активной мощности для одной операции подогрева расплава (МВт)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

  • Средние значения активной мощности для одной операции подогрева расплава распределены в диапазоне от 0,27 до 1,24 МВт. Обычно средняя развиваемая активная мощность составляет 0,7 МВт за одну операцию.

active_power_max — максимальное значение активной мощности для одной операции подогрева расплава (МВт)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

  • Максимальные значения активной мощности для одной операции подогрева расплава распределены в диапазоне от 0,27 до 1,46 МВт. Обычно максимальная развиваемая активная мощность составляет 1,1 МВт за одну операцию.

Реактивная мощность¶

In [137]:
col_name = 'Реактивная мощность, развиваемая за одну операцию подогрева, МВт'
pd.DataFrame(descriptive_statistics(
    data['reactive_power_min'], 'Минимальное значение').join(
descriptive_statistics(
    data['reactive_power_avg'], 'Среднее значение')).join(
descriptive_statistics(
    data['reactive_power_max'], 'Максимальное значение'))
    ).rename_axis(col_name, axis=1)
Out[137]:
Реактивная мощность, развиваемая за одну операцию подогрева, МВт Минимальное значение Среднее значение Максимальное значение
кол-во значений 2324 2324 2324
кол-во уникальных 2309 2323 2323
мин. 0.153777 0.196228 0.196228
-1.5IQR 0.127236 0.294688 0.317754
25 % 0.24 0.42 0.59
мода [0.257418] [0.5403865] [0.530982]
медиана 0.29 0.48 0.72
среднее ариф. 0.3 0.49 0.72
75 % 0.35 0.55 0.85
+1.5IQR 0.456545 0.674649 1.114011
макс. 0.875916 0.960763 1.270284
размах 0.722139 0.764535 1.074056
межквартильный размах 0.109769 0.126654 0.265419
In [138]:
label = ['Минимальное значение', 'Среднее значение', 'Максимальное значение']

plt.figure(figsize=(10, 3))
plt.title('График ядерной оценки плотности распределения')
sns.kdeplot(data['reactive_power_min'], color='coral')
sns.kdeplot(data['reactive_power_avg'], color='gold', shade=True)
sns.kdeplot(data['reactive_power_max'], color='sienna')
plt.xlabel('Реактивная мощность (на операцию подогрева), МВт')
plt.ylabel('Плотность распределения')
plt.legend(label)
plt.show()

reactive_power_min — минимальное значение реактивной мощности для одной операции подогрева расплава (МВт)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

  • Минимальные значения реактивной мощности для одной операции подогрева расплава распределены в диапазоне от 0,15 до 0,88 МВт. Обычно минимальная развиваемая реактивная мощность составляет 0,3 МВт за одну операцию.

reactive_power_avg — среднее значение реактивной мощности для одной операции подогрева расплава (МВт)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

  • Средние значения реактивной мощности для одной операции подогрева расплава распределены в диапазоне от 0,20 до 0,97 МВт. Обычно средняя развиваемая реактивная мощность составляет 0,5 МВт за одну операцию.

reactive_power_max — максимальное значение реактивной мощности для одной операции подогрева расплава (МВт)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

  • Максимальные значения реактивной мощности для одной операции подогрева расплава распределены в диапазоне от 0,20 до 1,27 МВт. Обычно максимальная развиваемая реактивная мощность составляет 0,7 МВт за одну операцию.

Коэффициент мощности¶

In [139]:
col_name = 'Коэффициент мощности, развиваемой за одну операцию подогрева'
pd.DataFrame(descriptive_statistics(
    data['power_factor_min'], 'Минимальное значение').join(
descriptive_statistics(
    data['power_factor_avg'], 'Среднее значение')).join(
descriptive_statistics(
    data['power_factor_max'], 'Максимальное значение'))
    ).rename_axis(col_name, axis=1)
Out[139]:
Коэффициент мощности, развиваемой за одну операцию подогрева Минимальное значение Среднее значение Максимальное значение
кол-во значений 2324 2324 2324
кол-во уникальных 2324 2324 2324
мин. 0.707722 0.739789 0.743036
-1.5IQR 0.72065 0.779 0.807719
25 % 0.76 0.8 0.82
мода [0.707722024438604, 0.7119254667035388, 0.7139... [0.7397892461266198, 0.7422799682440981, 0.743... [0.7430360587816858, 0.7436744060245243, 0.758...
медиана 0.77 0.81 0.83
среднее ариф. 0.77 0.81 0.83
75 % 0.79 0.81 0.84
+1.5IQR 0.824254 0.833025 0.861821
макс. 0.857042 0.857042 0.870445
размах 0.14932 0.117253 0.127409
межквартильный размах 0.034535 0.018008 0.018034
In [140]:
label = ['Минимальное значение', 'Среднее значение', 'Максимальное значение']

plt.figure(figsize=(10, 3))
plt.title('График ядерной оценки плотности распределения')
sns.kdeplot(data['power_factor_min'], color='coral')
sns.kdeplot(data['power_factor_avg'], color='gold', shade=True)
sns.kdeplot(data['power_factor_max'], color='sienna')
plt.xlabel('Коэффициент мощности (на операцию подогрева)')
plt.ylabel('Плотность распределения')
plt.legend(label)
plt.show()

power_factor_min — минимальное значение коэффициента мощности для одной операции подогрева расплава
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

  • Минимальные значения коэффициента мощности для одной операции подогрева расплава распределены в диапазоне от 0,71 до 0,86 МВт. Обычно минимальный коэффициент мощности составляет 0,77 МВт за одну операцию.

power_factor_avg — среднее значение коэффициента мощности для одной операции подогрева расплава
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

  • Средние значения коэффициента мощности для одной операции подогрева расплава распределены в диапазоне от 0,74 до 0,86 МВт. Обычно средний коэффициент мощности составляет 0,81 МВт за одну операцию.

power_factor_max — максимальное значение коэффициента мощности для одной операции подогрева расплава
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

  • Максимальные значения коэффициента мощности для одной операции подогрева расплава распределены в диапазоне от 0,74 до 0,87 МВт. Обычно максимальный коэффициент мощности составляет 0,83 МВт за одну операцию.

Время подогрева¶

In [141]:
descriptive_statistics(data['heating_time_sum'], 'Время подогрева, с')
Out[141]:
Время подогрева, с
кол-во значений 2324
кол-во уникальных 1036
мин. 57.0
-1.5IQR 160.0
25 % 581.0
мода [874.0]
медиана 778.0
среднее ариф. 808.2
75 % 993.0
+1.5IQR 1396.0
макс. 4189.0
размах 4132.0
межквартильный размах 412.0
In [142]:
plt.figure(figsize=(10, 3))
plt.title('График ядерной оценки плотности распределения')
sns.kdeplot(data['heating_time_sum'], color='gold', shade=True)
plt.xlabel('Время подогрева, с')
plt.ylabel('Плотность распределения')
plt.show()

full_power_sum — суммарное значение времени подогрева в ходе одной стадии легирования (с)
Признак является количественным, непрерывным.
Шкала измерения признака: интервальная шкала.

  • Для 2324 записей встречается 1036 различных уникальных значений.
  • Минимальное значение — 57 с (1 мин), максимальное значение — 4189 с (70 мин).
  • Мода — 874 с (14,6 мин), медиана — 778 с (13 мин), среднее арифметическое — 808 с (13,5 мин).
  • На графике ядерной оценки плотности наблюдается один максимум при времени 750 c (12,5 мин).
  • Значения распределены практически симметрично, половина всех значений лежит в диапазоне от 581 до 993 c (9,7 –16,6 мин).
  • Практически все значения лежат в пределах от 160 до 1396 c (2,7–23,3 мин). У распределения наблюдается "хвост" справа.
In [143]:
col_name = 'Время одной операции подогрева, с'
pd.DataFrame(descriptive_statistics(
    data['heating_time_min'], 'Минимальное значение, с').join(
descriptive_statistics(
    data['heating_time_avg'], 'Среднее значение, с')).join(
descriptive_statistics(
    data['heating_time_max'], 'Максимальное значение, с'))
    ).rename_axis(col_name, axis=1)
Out[143]:
Время одной операции подогрева, с Минимальное значение, с Среднее значение, с Максимальное значение, с
кол-во значений 2324 2324 2324
кол-во уникальных 197 1348 462
мин. 11.0 57.0 57.0
-1.5IQR 0.125 82.875 86.5
25 % 62.0 141.0 212.0
мода [62.0] [141.0, 173.0, 191.0] [244.0]
медиана 83.0 169.5 277.0
среднее ариф. 89.39 172.12 289.76
75 % 117.25 198.75 339.0
+1.5IQR 165.875 256.125 467.5
макс. 281.0 378.0 907.0
размах 270.0 321.0 850.0
межквартильный размах 55.25 57.75 127.0
In [144]:
label = ['Минимальное значение', 'Среднее значение', 'Максимальное значение']

plt.figure(figsize=(10, 3))
plt.title('График ядерной оценки плотности распределения')
sns.kdeplot(data['heating_time_min'], color='coral')
sns.kdeplot(data['heating_time_avg'], color='gold', shade=True)
sns.kdeplot(data['heating_time_max'], color='sienna')
plt.xlabel('Время одного подогрева, с')
plt.ylabel('Плотность распределения')
plt.legend(label)
plt.show()

heating_time_min — минимальное значение времени одной операции подогрева расплава (с)
Признак является количественным, непрерывным.
Шкала измерения признака: интервальная шкала.

  • Минимальные значения времени одной операции подогрева расплава распределены в диапазоне от 11 до 281 с (4,7 мин). Обычно минимальное время одной операции составляет 83 с (1,4 мин).

heating_time_avg — среднее значение времени одной операции подогрева расплава (с)
Признак является количественным, непрерывным.
Шкала измерения признака: интервальная шкала.

  • Средние значения времени одной операции подогрева расплава распределены в диапазоне от 57 до 378 с (1–6,3 мин). Обычно среднее время одной операции составляет 170 с (2,8 мин).

heating_time_max — максимальное значение времени одной операции подогрева расплава (с)
Признак является количественным, непрерывным.
Шкала измерения признака: интервальная шкала.

  • Максимальные значения времени одной операции подогрева расплава распределены в диапазоне от 57 до 907 с (1–15 мин). Обычно максимальное время одной операции составляет 277 с (4,6 мин).
In [145]:
descriptive_statistics(data['heating_count'], 'Количество операций подогрева')
Out[145]:
Количество операций подогрева
кол-во значений 2324
кол-во уникальных 15
мин. 1
-1.5IQR 2.0
25 % 4.0
мода [4]
медиана 5.0
среднее ариф. 4.7
75 % 6.0
+1.5IQR 8.0
макс. 16
размах 15
межквартильный размах 2.0
In [146]:
plt.figure(figsize=(10, 3))
plt.title('График распределения значений количества операций подогрева')
data['heating_count'].value_counts().sort_index().plot(kind='bar',
                                                       color='gold',
                                                       rot=0)
plt.xlabel('Количество операций подогрева')
plt.ylabel('Частота')
plt.show()

heating_count — количество операций подогрева
Признак является количественным, дискретным.
Шкала измерения признака: абсолютная шкала.

  • Для 2324 записей встречается 15 различных уникальных значений.
  • Минимальное значение — 1 операция, максимальное значение — 16 операций.
  • Мода — 4 операций, её частота — 637.
  • Медиана — 5 операций.
  • Практически все значения лежат в пределах от 2 до 8 операций.

Потреблённая энергия¶

In [147]:
descriptive_statistics(data['energy_sum'], 'Потреблённая энергия, МДж')
Out[147]:
Потреблённая энергия, МДж
кол-во значений 2324
кол-во уникальных 2324
мин. 33.430208
-1.5IQR 55.380027
25 % 457.92
мода [33.43020759374457, 35.525857072478495, 41.487...
медиана 631.23
среднее ариф. 670.23
75 % 841.82
+1.5IQR 1207.077699
макс. 4546.405812
размах 4512.975605
межквартильный размах 383.899224
In [148]:
plt.figure(figsize=(10, 3))
plt.title('График ядерной оценки плотности распределения')
sns.kdeplot(data['energy_sum'], color='gold', shade=True)
plt.xlabel('Потреблённая энергия (на стадию легирования), МДж')
plt.ylabel('Плотность распределения')
plt.show()

energy_sum — суммарное значение потреблённой энергии (МДж)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

  • Все значения являются уникальными.
  • Минимальное значение — 33 МДж, максимальное значение — 4546 МДж.
  • Медиана — 631 МДж, среднее арифметическое — 670 МДж.
  • На графике ядерной оценки плотности наблюдается один максимум при энергии 600 МДж.
  • Значения распределены практически симметрично, половина всех значений лежит в диапазоне от 458 до 842 МДж.
  • Практически все значения лежат в пределах от 55 до 1207 МДж. У распределения наблюдается "хвост" справа.
In [149]:
col_name = 'Потребляемая за одну операцию подогрева энергия, МДж'
pd.DataFrame(descriptive_statistics(
    data['energy_min'], 'Минимальное значение').join(
descriptive_statistics(
    data['energy_avg'], 'Среднее значение')).join(
descriptive_statistics(
    data['energy_max'], 'Максимальное значение'))
    ).rename_axis(col_name, axis=1)
Out[149]:
Потребляемая за одну операцию подогрева энергия, МДж Минимальное значение Среднее значение Максимальное значение
кол-во значений 2324 2324 2324
кол-во уникальных 2324 2324 2324
мин. 6.409531 25.227273 28.649852
-1.5IQR -3.282212 43.811574 12.822143
25 % 38.54 108.96 175.08
мода [6.409530855986029, 6.501806548023787, 7.03108... [25.227272609939007, 31.31340737231741, 33.430... [28.64985159816941, 33.43020759374457, 35.5258...
медиана 55.81 136.27 240.71
среднее ариф. 62.0 142.45 264.55
75 % 77.94 170.6 327.01
+1.5IQR 114.905758 228.718856 468.589087
макс. 277.867924 436.387492 1069.548361
размах 271.458393 411.160219 1040.898509
межквартильный размах 39.39599 61.635761 151.922315
In [150]:
label = ['Минимальное значение', 'Среднее значение', 'Максимальное значение']

plt.figure(figsize=(10, 3))
plt.title('График ядерной оценки плотности распределения')
sns.kdeplot(data['energy_min'], color='coral')
sns.kdeplot(data['energy_avg'], color='gold', shade=True)
sns.kdeplot(data['energy_max'], color='sienna')
plt.xlabel('Потребляемая энергия (за операцию подогрева), МДж')
plt.ylabel('Плотность распределения')
plt.legend(label)
plt.show()

energy_min — минимальное значение энергии, потребляемой за одну операцию подогрева расплава (МДж)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

  • Минимальные значения энергии, потребляемой за одну операцию подогрева расплава, распределены в диапазоне от 6 до 278 МДж. Обычно минимальная потребляемая энергия составляет 56 МДж за одну операцию.

energy_avg — среднее значение энергии, потребляемой за одну операцию подогрева расплава (МДж)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

  • Средние значения энергии, потребляемой за одну операцию подогрева расплава, распределены в диапазоне от 25 до 436 МДж. Обычно средняя потребляемая энергия составляет 136 МДж за одну операцию.

energy_max — максимальное значение энергии, потребляемой за одну операцию подогрева расплава (МДж)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

  • Максимальные значения энергии, потребляемой за одну операцию подогрева расплава, распределены в диапазоне от 29 до 1070 МВт. Обычно максимальная потребляемая энергия составляет 241 МДж за одну операцию.

Объём инертного газа¶

In [151]:
descriptive_statistics(data['gas'], 'Объём инертного газа, м$^3$')
Out[151]:
Объём инертного газа, м$^3$
кол-во значений 2324
кол-во уникальных 2324
мин. 0.008399
-1.5IQR -0.303242
25 % 7.28
мода [0.0083985291, 0.0166956024, 0.3642557946, 0.8...
медиана 10.1
среднее ариф. 11.38
75 % 14.22
+1.5IQR 20.504615
макс. 77.99504
размах 77.986641
межквартильный размах 6.935952
In [152]:
plt.figure(figsize=(10, 3))
plt.title('График ядерной оценки плотности распределения')
sns.kdeplot(data['gas'], color='gold', shade=True)
plt.xlabel('Объём инертного газа, м$^3$')
plt.ylabel('Плотность распределения')
plt.show()

gas — суммарное значение полной мощности (м$^3$)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

  • Все значения являются уникальными.
  • Минимальное значение — 0,01 м$^3$, максимальное значение — 78 м$^3$.
  • Медиана — 10 м$^3$, среднее арифметическое — 11 м$^3$.
  • На графике ядерной оценки плотности наблюдается один максимум при объёме 9 м$^3$.
  • Значения распределены практически симметрично, половина всех значений лежит в диапазоне от 7 до 14 м$^3$. Наблюдается небольшое плечо справа от максимума.
  • Практически все значения не превышают 20,5 м$^3$. У распределения наблюдается "хвост" справа.

Легирующие добавки¶

In [153]:
descriptive_statistics(data['bulk_sum'], 'Общая масса сыпучих материалов, кг')
Out[153]:
Общая масса сыпучих материалов, кг
кол-во значений 2324
кол-во уникальных 963
мин. 19.0
-1.5IQR 75.0
25 % 440.0
мода [582.0]
медиана 609.0
среднее ариф. 610.08
75 % 796.0
+1.5IQR 1143.0
макс. 3235.0
размах 3216.0
межквартильный размах 356.0
In [154]:
plt.figure(figsize=(10, 3))
plt.title('График ядерной оценки плотности распределения')
sns.kdeplot(data['bulk_sum'], color='gold', shade=True)
plt.xlabel('Общая масса сыпучих материалов, кг')
plt.ylabel('Плотность распределения')
plt.show()

bulk_sum — общая масса сыпучих материалов (кг)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

  • Для 2324 записей встречается 963 различных уникальных значений.
  • Минимальное значение — 19 кг, максимальное значение — 3235 кг.
  • Медиана — 609 кг, среднее арифметическое — 610 кг.
  • На графике ядерной оценки плотности наблюдается один отчётливый максимум при массе 610 кг, а также ещё один небольшой максимум при массе 150 кг и небольшое плечо справа при массе 1000 кг.
  • Половина всех значений лежит в диапазоне от 440 до 796 кг.
  • Практически все значения расположены от 75 до 1143 кг. У распределения наблюдается "хвост" справа.
In [155]:
descriptive_statistics(
    data['bulk_count'], 'Количество разных видов внесённых сыпучих материалов')
Out[155]:
Количество разных видов внесённых сыпучих материалов
кол-во значений 2324
кол-во уникальных 7
мин. 1
-1.5IQR 2.5
25 % 3.0
мода [4]
медиана 4.0
среднее ариф. 3.59
75 % 4.0
+1.5IQR 5.5
макс. 7
размах 6
межквартильный размах 1.0
In [156]:
plt.figure(figsize=(10, 3))
plt.title('График распределения значений количества операций подогрева')
data['bulk_count'].value_counts().sort_index().plot(kind='bar',
                                                    color='gold',
                                                    rot=0)
plt.xlabel('Количество разных видов внесённых сыпучих материалов')
plt.ylabel('Частота')
plt.show()

bulk_count — количество разных видов внесённых сыпучих материалов
Признак является количественным, дискретным.
Шкала измерения признака: абсолютная шкала.

  • Для 2324 записей встречается 7 различных уникальных значений.
  • Минимальное значение — 1 вид, максимальное значение — 7 видов сыпучего материала.
  • Мода — 4 вида материалов, её частота — 1095.
  • Медиана — 4 вида материалов.
  • Практически все значения лежат в пределах от 2 до 6 видов сыпучего материала.
In [157]:
descriptive_statistics(
    data['wire_sum'], 'Общая масса проволочных материалов, кг')
Out[157]:
Общая масса проволочных материалов, кг
кол-во значений 2324
кол-во уникальных 2077
мин. 1.9188
-1.5IQR 22.346231
25 % 89.05
мода [105.066002]
медиана 116.11
среднее ариф. 125.2
75 % 151.56
+1.5IQR 209.866011
макс. 568.777664
размах 566.858864
межквартильный размах 62.506593
In [158]:
plt.figure(figsize=(10, 3))
plt.title('График ядерной оценки плотности распределения')
sns.kdeplot(data['wire_sum'], color='gold', shade=True)
plt.xlabel('Общая масса проволочных материалов, кг')
plt.ylabel('Плотность распределения')
plt.show()

wire_sum — общая масса проволочных материалов (кг)
Признак является количественным, непрерывным.
Шкала измерения признака: шкала отношений.

  • Для 2324 записей встречается 2077 различных уникальных значений.
  • Минимальное значение — 2 кг, максимальное значение — 569 кг.
  • Медиана — 116 кг, среднее арифметическое — 125 кг.
  • На графике ядерной оценки плотности наблюдается один отчётливый максимум при массе 110 кг.
  • Половина всех значений лежит в диапазоне от 89 до 152 кг.
  • Практически все значения расположены от 22 до 210 кг. У распределения наблюдается "хвост" справа.
In [159]:
descriptive_statistics(data['wire_count'],
    'Количество разных видов внесённых проволочных материалов')
Out[159]:
Количество разных видов внесённых проволочных материалов
кол-во значений 2324
кол-во уникальных 5
мин. 1
-1.5IQR -0.5
25 % 1.0
мода [1]
медиана 1.0
среднее ариф. 1.4
75 % 2.0
+1.5IQR 2.5
макс. 5
размах 4
межквартильный размах 1.0
In [160]:
plt.figure(figsize=(10, 3))
plt.title('График распределения значений количества операций подогрева')
data['wire_count'].value_counts().sort_index().plot(kind='bar',
                                                    color='gold',
                                                    rot=0)
plt.xlabel('Количество разных видов внесённых проволочных материалов')
plt.ylabel('Частота')
plt.show()

wire_count — количество разных видов внесённых сыпучих материалов
Признак является количественным, дискретным.
Шкала измерения признака: абсолютная шкала.

  • Для 2324 записей встречается 5 различных уникальных значений.
  • Минимальное значение — 1 вид, максимальное значение — 5 видов сыпучего материала.
  • Мода — 1 вид материалов, её частота — 1478.
  • Медиана — 1 вид материалов.
  • Практически все значения лежат в пределах от 1 до 2 видов сыпучего материала.

Промежуточный вывод

  • Температура расплава, выходящего после стадии легирования, составляет (1593$\pm$16) $^{\circ}$C.
  • Наличие помимо основного пика при 1593 $^{\circ}$C ещё пиков при 1575 $^{\circ}$C и 1620 $^{\circ}$C может говорить о том, что на предприятии выпускают не менее трёх марок стали, производство которых требует разных температурных режимов.
  • Температура поступающего на стадию легирования расплава в среднем составляет (1587$\pm$48) $^{\circ}$C. Широкое распределение значений температуры может свидетельствовать о том, что не представляется возможным выдерживать температуру расплава, выходящего из сталеплавильной печи, в узком диапазоне.
  • Среднее время легирования составляет (30$\pm$4) мин, и в подавляющем большинстве случаев время легирования не превышает 65 мин.
  • Минимальное время легирования составляет 6 мин. Самое долгое легирование продолжалось 6,6 ч — столько времени потребовалось, чтобы корректировать температуру расплава (нагревать его).
  • Значение полной суммарной мощности, которая достигается при производстве одной партии стали, в среднем составляет (3,8$\pm$2,9) МВт.
    • На одну операцию подогрева расплава приходится в среднем 0,8 МВт полной мощности. Причём развивают минимальную полную мощность, равную 0,5 МВт, а максимальную — 1,2 МВт.
    • Средняя активная мощность, развиваемая за операцию подогрева расплава, составляет 0,7 МВт, минимальная — 0,4 МВт, максимальна — 1,1 МВт.
    • Средняя реактивная мощность, развиваемая за операцию подогрева расплава, составляет 0,5 МВт, минимальная — 0,3 МВт, максимальна — 0,7 МВт.
    • Среднее значение коэффициента мощности, развиваемой за операцию подогрева расплава, составляет 0,81 МВт, минимальное — 0,77 МВт, максимальное — 0,83 МВт.
  • В ходе легирования расплав подогревают от 2 до 8 раз, чаще всего 4–5 раз.
  • Обычно на работу электродов и подогрев расплава уходит в сумме всех операций от 2 до 23 минут, причём всего в среднем уходит 13–14 минут на подогрев расплава.
    • Среднее время одной операции подогрева составляет 2,8 мин, минимальное — 1,4 мин, максимальное — 4,6 мин.
  • Количество потребляемой энергии в ходе проведения стадии легирования почти всегда изменяется в пределах 55–1207 МДж, причём среднее значение потребляемой энергии составляет 630 МДж.
    • Среднее количество энергии, потребляемой за одну операцию подогрева расплава, составляет 136 МДж, минимальное — 56 МДж, максимальное — 241 МДж.
  • Объём пропускаемого через расплав газа при производстве одной партии почти всегда не превышает 20,5 м$^3$. В среднем расходуется 10–11 м$^3$ инертного газа на производство одной партии стали.
  • В среднем в каждый сплав в качестве легирующих добавок вносят по 610 кг сыпучего материала и 125 кг проволочного материала. Причём в среднем сыпучих материалов вносят 4 различных вида, а проволочных — 1 вид.
  • В целом, стадии легирования сопровождаются операциями по внесению от 2 до 6 различных видов сыпучего материала общей массы 75–1143 кг и 1–2 видов проволочного материала общей массой 22–210 кг.

Корреляционный анализ¶

Построим матрицу корреляции признаков, рассчитав коэффициенты корреляции Пирсона.

In [161]:
corr = data.drop(['key'], axis=1).corr()

plt.figure(figsize=(11, 9))
plt.title('Матрица корреляции признаков')

mask = np.triu(np.ones_like(corr, dtype=bool))
cmap = sns.diverging_palette(230, 20, as_cmap=True)
sns.heatmap(corr, mask=mask, cmap=cmap, vmax=1, vmin=-1, center=0,
            square=True, linewidths=.5, cbar_kws={"shrink": .5})
plt.xlabel('Наименования признаков')
plt.ylabel('Наименования признаков')
plt.show()
In [162]:
corr = corr[(abs(corr) >= 0.8) &
            (corr != 1)
           ].dropna(thresh=1).dropna(thresh=1, axis=1)

plt.figure(figsize=(11, 9))
plt.title('Матрица корреляции признаков')

mask = np.triu(np.ones_like(corr, dtype=bool))
cmap = sns.diverging_palette(230, 20, as_cmap=True)
sns.heatmap(corr, mask=mask, cmap=cmap, vmax=1, vmin=0.8, center=0.7,
            annot=True, square=True, linewidths=.5, cbar_kws={"shrink": .5})

plt.xlabel('Наименования признаков')
plt.ylabel('Наименования признаков')
plt.show()

Признаки, коэффициент корреляции между которыми по модулю равен 0,9 и больше, будем считать обладающими высокой степенью линейной связи. Такой корреляцией обладают значения, характеризующие активную, реактивную и полную мощности. Это ожидаемо, поскольку все три связаны одной формулой-соотношением. Кроме того, обнаруживается высокая степень линейной положительной связи между признаками wire_8 и bulk_9. Вероятно, эти материалы добавляются к расплаву вместе, с сохранением отношения их масс. Высокую корреляцию имеют значения признаков общей переданной энергии расплаву и общим временем нагрева расплава.

Обратим также внимание на признаки, коэффициент корреляции между которыми равен или больше 0,8. Со значениями полной суммарной мощности коррелируют значения суммарной энергии (потому что она прямо пропорциональна ей) и значение количества операций подогрева. Коррелируют значения общей (суммарной) массы сыпучих материалов (bulk_sum) и материала 12 (bulk_12).

Построение моделей¶

Подготовка данных для обучения¶

Удаление лишних признаков¶

Значения признака key являются уникальными, измеряются в порядковой шкале, которая может быть с лёгкостью заменена на любую другую порядковую шкалу. Например, можно использовать индексы набора данных для различения партий. Эти значения не являются важными для обучения модели, более того, будет ошибочным использовать их для обучения. Удалим этот признак.

Также удалим некоторые из признаков, которые имеют сильную корреляцию с другими признаками.

In [163]:
data.drop(['key',
           'active_power_avg',
           'active_power_min',
           'active_power_max',
           'reactive_power_avg',
           'reactive_power_min',
           'reactive_power_max',
           'heating_count',
           'energy_sum',
           'bulk_sum',
           'wire_8'],
          axis=1, inplace=True)
In [164]:
corr = data.corr()
((abs(corr) >= 0.8) & (corr != 1)).sum().sum()
Out[164]:
0
In [165]:
data.columns
Out[165]:
Index(['last_temperature', 'first_temperature', 'process_time',
       'full_power_sum', 'full_power_avg', 'full_power_min', 'full_power_max',
       'power_factor_avg', 'power_factor_min', 'power_factor_max',
       'heating_time_sum', 'heating_time_avg', 'heating_time_min',
       'heating_time_max', 'energy_avg', 'energy_min', 'energy_max', 'gas',
       'bulk_1', 'bulk_2', 'bulk_3', 'bulk_4', 'bulk_5', 'bulk_6', 'bulk_7',
       'bulk_8', 'bulk_9', 'bulk_10', 'bulk_11', 'bulk_12', 'bulk_13',
       'bulk_14', 'bulk_15', 'bulk_count', 'wire_1', 'wire_2', 'wire_3',
       'wire_4', 'wire_5', 'wire_6', 'wire_7', 'wire_9', 'wire_sum',
       'wire_count'],
      dtype='object')

Разделение данных на выборки¶

Выделим из данных целевой признак last_temperature.

In [166]:
features = data.drop(['last_temperature'], axis=1)
target = data['last_temperature']

Поскольку отдельной тестовой выборки нет, разделим данные на тренировочную и тестовую выборки в отношении 3 : 1.

In [167]:
features_train, features_test, target_train, target_test = train_test_split(
    features, target, test_size=0.25, random_state=RANDOM_STATE)

Посмотрим, какие выборки получились после разделения.

In [168]:
features_train.shape
Out[168]:
(1743, 43)
In [169]:
features_test.shape
Out[169]:
(581, 43)

Обучение моделей¶

Поскольку признак last_temperaturer — количественный, непрерывный, следовательно, необходимо решить задачу регрессии.

Зафиксируем псевдослучайность для алгоритмов обучения.

Оценку качества обученных моделей будем проводить, рассчитывая значение среднего абсолютного отклонения (MAE). Обученная модель будет считаться выполняющей качественный прогноз, если значение среднего абсолютного отклонения не будет превышать 6,8 $^{\circ}$C.

Для того чтобы получить максимально высокое качество предсказания, нужно перебрать в алгоритмах обучения разные значения гиперпараметров. Наилучшими гиперпараметрами для моделей признаем те, при которых получится минимальное значение MAE, оценённое при проведении кросс-валидации.

Валидация¶

Подбор параметров моделей и оценку качества обучаемых моделей будем производить кросс-валидацией. Подвыборки будем формировать схожими по размеру тестовой выборке. Таким образом, количество формируемых подвыборок для обучения одной модели равно 3.

In [170]:
CV = 3
SCORER = 'neg_mean_absolute_error'

Обозначим, какие признаки считать в наборе данных количественными.

In [171]:
numerical_columns = features.columns.tolist()

Простая модель¶

In [172]:
class Dummy(BaseEstimator, RegressorMixin):

    def __init__(self, strategy):

        self.strategy = strategy

    def fit(self, X, y=None):

        return self

    def predict(self, X):

        return X[self.strategy]
In [173]:
%%time

model_dummy = Dummy(strategy='first_temperature')

model_dummy_score = cross_val_score(
    model_dummy,
    features_train,
    target_train,
    cv=CV,
    scoring=SCORER,
    error_score='raise',
    n_jobs=-1)

print('Простая модель, предсказывающая значение начальной температуры')
print('\nMAE =', abs(model_dummy_score).mean().round(2), u'\u2103\n')
Простая модель, предсказывающая значение начальной температуры

MAE = 19.11 ℃

CPU times: user 37.8 ms, sys: 39.7 ms, total: 77.5 ms
Wall time: 1.28 s
In [174]:
%%time

STRATEGY = 'mean'

model_dr = DummyRegressor(strategy=STRATEGY)
model_dr_score = cross_val_score(
    model_dr,
    features_train,
    target_train,
    cv=CV,
    scoring=SCORER,
    error_score='raise',
    n_jobs=-1)

print('Простая модель, предсказывающая среднее арифметическое значение')
print('\nMAE =', abs(model_dr_score).mean().round(2), u'\u2103\n')
Простая модель, предсказывающая среднее арифметическое значение

MAE = 8.24 ℃

CPU times: user 9.01 ms, sys: 1.83 ms, total: 10.8 ms
Wall time: 26.2 ms

Линейная регрессия¶

In [175]:
%%time

pipeliner = Pipeline([
    ('transformer', ColumnTransformer([
        ('scaler', StandardScaler(), numerical_columns)
    ])),
    ('model', LinearRegression(n_jobs=-1))])

model_lr_score = cross_val_score(
    pipeliner,
    features_train,
    target_train,
    cv=CV,
    scoring=SCORER,
    error_score='raise',
    n_jobs=-1)

print('Модель линейной регрессии')
print('\nMAE =', abs(model_lr_score).mean().round(2), u'\u2103\n')
Модель линейной регрессии

MAE = 6.15 ℃

CPU times: user 14.4 ms, sys: 1.07 ms, total: 15.5 ms
Wall time: 99.2 ms

Стохастический градиентный спуск¶

In [176]:
%%time

pipeliner = Pipeline([
    ('transformer', ColumnTransformer([
        ('scaler', StandardScaler(), numerical_columns)
    ])),
    ('model', SGDRegressor(random_state=RANDOM_STATE))])

parameters = {'model__alpha': [10**n for n in range(1, -7, -1)],
              'model__tol': [10**n for n in range(1, -6, -1)],
              'model__eta0': [10**n for n in range(1, -4, -1)]}

sgdr = RandomizedSearchCV(
    pipeliner,
    param_distributions=parameters,
    cv=CV,
    n_iter=100,
    scoring=SCORER,
    random_state=RANDOM_STATE,
    n_jobs=-1,
    error_score='raise')

sgdr.fit(features_train, target_train)

print('Модель стохастического градиентного спуска')
print('\nMAE =', round(abs(sgdr.best_score_), 2), u'\u2103\n')
print('\nПараметры наилучшей модели:',
      pd.DataFrame(sgdr.best_params_, index = ['']).T)
Модель стохастического градиентного спуска

MAE = 6.11 ℃


Параметры наилучшей модели:                    
model__tol    0.100
model__eta0   0.010
model__alpha  0.001
CPU times: user 362 ms, sys: 25.2 ms, total: 387 ms
Wall time: 4.65 s

Гребневая регрессия¶

In [177]:
%%time

pipeliner = Pipeline([
    ('transformer', ColumnTransformer([
        ('scaler', StandardScaler(), numerical_columns)
    ])),
    ('model', Ridge(random_state=RANDOM_STATE))])


parameters = {'model__alpha': [10**n for n in range(2, -2, -1)],
              'model__tol': [10**n for n in range(1, -6, -1)],
              'model__max_iter': [None]+[10**n for n in range(1, 4, 1)]}

ridge = RandomizedSearchCV(
    pipeliner,
    param_distributions=parameters,
    cv=CV,
    n_iter=100,
    scoring=SCORER,
    random_state=RANDOM_STATE,
    n_jobs=-1,
    error_score='raise')

ridge.fit(features_train, target_train)

print('Модель гребневой регрессии')
print('\nMAE =', round(abs(ridge.best_score_), 2), u'\u2103\n')
print('\nПараметры наилучшей модели:',
      pd.DataFrame(ridge.best_params_, index = ['']).T)
Модель гребневой регрессии

MAE = 6.13 ℃


Параметры наилучшей модели:                          
model__tol         0.0001
model__max_iter  100.0000
model__alpha      10.0000
CPU times: user 317 ms, sys: 22.3 ms, total: 340 ms
Wall time: 2.83 s

Регрессия LASSO¶

In [178]:
%%time

pipeliner = Pipeline([
    ('transformer', ColumnTransformer([
        ('scaler', StandardScaler(), numerical_columns)
    ])),
    ('model', Lasso(random_state=RANDOM_STATE))])

parameters = {'model__alpha': [10**n for n in range(3, -4, -1)],
              'model__tol': [10**n for n in range(1, -6, -1)],
              'model__max_iter': [10**n for n in range(1, 6, 1)]}

lasso = RandomizedSearchCV(
    pipeliner,
    param_distributions=parameters,
    cv=CV,
    n_iter=100,
    scoring=SCORER,
    random_state=RANDOM_STATE,
    n_jobs=-1,
    error_score='raise')

lasso.fit(features_train, target_train)

print('Модель регрессии Lasso')
print('\nMAE =', round(abs(lasso.best_score_), 2), u'\u2103\n')
print('\nПараметры наилучшей модели:',
      pd.DataFrame(lasso.best_params_, index = ['']).T)
Модель регрессии Lasso

MAE = 6.07 ℃


Параметры наилучшей модели:                            
model__tol          0.00001
model__max_iter  1000.00000
model__alpha        0.10000
CPU times: user 345 ms, sys: 48.9 ms, total: 394 ms
Wall time: 2.89 s

Дерево решений¶

In [179]:
%%time

pipeliner = Pipeline([
    ('transformer', ColumnTransformer([
        ('scaler', StandardScaler(), numerical_columns)
    ])),
    ('model', DecisionTreeRegressor(random_state=RANDOM_STATE))])

parameters = {'model__max_depth': [None]+[n for n in range(1, 31, 1)],
              'model__min_samples_leaf': [n for n in range(1, 31, 1)],
              'model__min_samples_split': [n for n in range(2, 11, 1)]}

dtr = RandomizedSearchCV(
    pipeliner,
    param_distributions=parameters,
    cv=CV,
    n_iter=100,
    scoring=SCORER,
    random_state=RANDOM_STATE,
    n_jobs=-1,
    error_score='raise')

dtr.fit(features_train, target_train)

print('Модель решающего дерева')
print('\nMAE =', round(abs(dtr.best_score_), 2), u'\u2103\n')
print('\nПараметры наилучшей модели:',
      pd.DataFrame(dtr.best_params_, index = ['']).T)
Модель решающего дерева

MAE = 7.49 ℃


Параметры наилучшей модели:                             
model__min_samples_split   3
model__min_samples_leaf   30
model__max_depth          11
CPU times: user 356 ms, sys: 88.5 ms, total: 445 ms
Wall time: 4.63 s

Случайный лес¶

In [180]:
%%time

pipeliner = Pipeline([
    ('transformer', ColumnTransformer([
        ('scaler', StandardScaler(), numerical_columns)
    ])),
    ('model', RandomForestRegressor(random_state=RANDOM_STATE, n_jobs=-1))])

parameters = {'model__n_estimators': [n for n in range(10, 310, 10)],
              'model__max_depth': [None]+[n for n in range(1, 11, 1)]}

rfr = RandomizedSearchCV(
    pipeliner,
    param_distributions=parameters,
    cv=CV,
    n_iter=100,
    scoring=SCORER,
    random_state=RANDOM_STATE,
    n_jobs=-1,
    error_score='raise')

rfr.fit(features_train, target_train)

print('Модель случайного леса')
print('\nMAE =', round(abs(rfr.best_score_), 2), u'\u2103\n')
print('\nПараметры наилучшей модели:',
      pd.DataFrame(rfr.best_params_, index = ['']).T)
Модель случайного леса

MAE = 6.48 ℃


Параметры наилучшей модели:                          
model__n_estimators   170
model__max_depth     None
CPU times: user 8.13 s, sys: 491 ms, total: 8.62 s
Wall time: 5min 8s

Градиентный бустинг¶

Базовая модель градиентного бустинга¶
In [181]:
%%time

pipeliner = Pipeline([
    ('transformer', ColumnTransformer([
        ('scaler', StandardScaler(), numerical_columns)
    ])),
    ('model', GradientBoostingRegressor())])

parameters = {'model__n_estimators': [10, 20, 50, 100, 200, 500, 1000],
              'model__learning_rate':
               [0.005, 0.01, 0.05]+[0.1*n for n in range(1, 2)]}

gbr = RandomizedSearchCV(
    pipeliner,
    param_distributions=parameters,
    cv=CV,
    n_iter=100,
    scoring=SCORER,
    random_state=RANDOM_STATE,
    n_jobs=-1,
    error_score='raise')

gbr.fit(features_train, target_train)

print('Модель градиентного бустинга на основе алгоритма scikit-learn')
print('\nMAE =', round(abs(gbr.best_score_), 2), u'\u2103\n')
print('\nПараметры наилучшей модели:',
      pd.DataFrame(gbr.best_params_, index = ['']).T)
Модель градиентного бустинга на основе алгоритма scikit-learn

MAE = 6.13 ℃


Параметры наилучшей модели:                            
model__n_estimators   200.0
model__learning_rate    0.1
CPU times: user 3.52 s, sys: 215 ms, total: 3.73 s
Wall time: 2min
LightGBM¶
In [182]:
%%time

pipeliner = Pipeline([
    ('transformer', ColumnTransformer([
        ('scaler', StandardScaler(), numerical_columns)
    ])),
    ('model', LGBMRegressor())])

parameters = {'model__n_estimators': [10, 20, 50, 100, 200, 500, 1000],
              'model__learning_rate':
               [0.005, 0.01, 0.05]+[0.1*n for n in range(1, 2)]}

lightgbm = RandomizedSearchCV(
    pipeliner,
    param_distributions=parameters,
    cv=CV,
    n_iter=100,
    scoring=SCORER,
    random_state=RANDOM_STATE,
    n_jobs=-1,
    error_score='raise')

lightgbm.fit(features_train, target_train)

print('Модель градиентного бустинга на основе алгоритма LightGBM')
print('\nMAE =', round(abs(lightgbm.best_score_), 2), u'\u2103\n')
print('\nПараметры наилучшей модели:',
      pd.DataFrame(lightgbm.best_params_, index = ['']).T)
[LightGBM] [Warning] Auto-choosing row-wise multi-threading, the overhead of testing was 0.000261 seconds.
You can set `force_row_wise=true` to remove the overhead.
And if memory is not enough, you can set `force_col_wise=true`.
[LightGBM] [Info] Total Bins 5709
[LightGBM] [Info] Number of data points in the train set: 1743, number of used features: 35
[LightGBM] [Info] Start training from score 1593.498566
Модель градиентного бустинга на основе алгоритма LightGBM

MAE = 6.28 ℃


Параметры наилучшей модели:                              
model__n_estimators   1000.00
model__learning_rate     0.01
CPU times: user 2.47 s, sys: 88.5 ms, total: 2.56 s
Wall time: 35.6 s
XGBoost¶
In [183]:
%%time

pipeliner = Pipeline([
    ('transformer', ColumnTransformer([
        ('scaler', StandardScaler(), numerical_columns)
    ])),
    ('model', XGBRegressor())])

parameters = {'model__n_estimators': [10, 20, 50, 100, 200, 500, 1000],
              'model__learning_rate':
               [0.005, 0.01, 0.05]+[0.1*n for n in range(1, 2)]}

xgboost = RandomizedSearchCV(
    pipeliner,
    param_distributions=parameters,
    cv=CV,
    n_iter=100,
    scoring=SCORER,
    random_state=RANDOM_STATE,
    n_jobs=-1,
    error_score='raise')

xgboost.fit(features_train, target_train)

print('Модель градиентного бустинга на основе алгоритма XGBoost')
print('\nMAE =', round(abs(xgboost.best_score_), 2), u'\u2103\n')
print('\nПараметры наилучшей модели:',
      pd.DataFrame(xgboost.best_params_, index = ['']).T)
Модель градиентного бустинга на основе алгоритма XGBoost

MAE = 6.33 ℃


Параметры наилучшей модели:                             
model__n_estimators   200.00
model__learning_rate    0.05
CPU times: user 2.53 s, sys: 178 ms, total: 2.71 s
Wall time: 1min 33s
CatBoost¶
In [184]:
%%time

model_catboost = CatBoostRegressor(verbose=False)

parameters = {'n_estimators': [10, 20, 50, 100, 200, 500, 1000],
              'learning_rate':
               [0.005, 0.01, 0.05]+[0.1*n for n in range(1, 2)]}

catboost = RandomizedSearchCV(
    model_catboost,
    param_distributions=parameters,
    cv=CV,
    n_iter=100,
    scoring=SCORER,
    random_state=RANDOM_STATE,
    n_jobs=-1,
    error_score='raise')

catboost.fit(features_train, target_train)

print('Модель градиентного бустинга на основе алгоритма CatBoost')
print('\nMAE =', round(abs(catboost.best_score_), 2), u'\u2103\n')
print('\nПараметры наилучшей модели:',
      pd.DataFrame(catboost.best_params_, index = ['']).T)
Модель градиентного бустинга на основе алгоритма CatBoost

MAE = 6.07 ℃


Параметры наилучшей модели:                      
n_estimators   500.00
learning_rate    0.05
CPU times: user 5.07 s, sys: 272 ms, total: 5.34 s
Wall time: 2min

Промежуточный вывод

  • Наименьшее значение среднего абсолютного отклонения предсказаний (MAE = 6,07 $^{\circ}$C) демонстрирует модель регрессии LASSO с максимальным числом итераций — 1000, альфой — 0,1 и порогом остановки обучения — 0,00001.

Оценка модели¶

Демонстрация работы модели¶

In [185]:
predictions = lasso.best_estimator_.predict(features_test)

print('Модель регрессии Lasso')
print('\nЗначение среднего абсолютного отклонения на тестовой выборке')
print('MAE =',
      round(abs(mean_absolute_error(target_test, predictions)), 2), u'\u2103')
Модель регрессии Lasso

Значение среднего абсолютного отклонения на тестовой выборке
MAE = 5.86 ℃

Оценка значимости признаков¶

In [186]:
lasso_coef = pd.DataFrame(lasso.feature_names_in_, columns=['feature']).join(
    pd.DataFrame(lasso.best_estimator_.named_steps['model'].coef_,
                 columns=['coef']))
lasso_coef = lasso_coef.sort_values(by='coef',
                                    ascending=False).set_index('feature')
lasso_coef.head()
Out[186]:
coef
feature
heating_time_sum 8.530731
first_temperature 7.465756
wire_1 1.353724
bulk_15 1.156602
heating_time_avg 0.573775
In [187]:
df = lasso_coef[lasso_coef['coef'] !=0]
plt.figure(figsize=(9, 9))
plt.title('Диаграмма значимости признаков')
df['coef'].plot(kind='barh', color='gold', rot=0)
plt.xlabel('Коэффициенты регрессии LASSO')
plt.ylabel('Наименования признаков')
plt.show()
In [188]:
df = abs(lasso_coef[lasso_coef['coef'] !=0]).sort_values(by='coef',
                                                         ascending=False)
plt.figure(figsize=(9, 9))
plt.title('Диаграмма значимости признаков')
df['coef'].plot(kind='barh', color='coral', rot=0)
plt.xlabel('Абсолютные значения коэффициентов регрессии LASSO')
plt.ylabel('Наименования признаков')
plt.show()
In [189]:
lasso_coef[lasso_coef['coef'] == 0].index
Out[189]:
Index(['wire_6', 'wire_5', 'wire_sum', 'bulk_12', 'bulk_10', 'bulk_8',
       'wire_count', 'full_power_sum', 'energy_max', 'energy_min',
       'energy_avg', 'full_power_avg', 'heating_time_min'],
      dtype='object', name='feature')
  • Наибольшую значимость для построения предсказания имеют значения первоначальной температуры, общего времени подогрева расплава и времени проведения процесса легирования.
  • Меньшую, но ещё высокую значимость имеют массы сыпучих материалов номер 1, 2, 6, 15 и проволочных материалов номер 1, 2, 4, 7, а также количество различных видов сыпучих материалов, вносимых в расплав.
  • Ещё меньшую значимость имеют среднее и максимальное время нагрева за одну операцию, минимальная полная мощность за операцию, минимальное, максимальное и среднее значение коэффициента мощности, рассчитанного для каждой операции.
  • Не имеют значения для построения модели сведения о потреблённой за операцию энергии (минимальной, максимальной и средней), минимальном времени подогрева за операцию, сведения о суммарном значении полной мощности и среднего значения полной мощности, развиваемой в результате операции подогрева расплава. Не важны для построения прогноза значения массы сыпучих материалов номер 8, 10, 12 и проволочных материалов номер 5, 6, общей массы проволочных материалов и количества различных их видов.
  • Остальные признаки имеют весовые коэффициенты, близкие к нулю, поэтому они не оказывают значимого влияния на построение прогноза.

Общий вывод¶

  1. Для целей предсказания конечной температуры расплава стали, выходящего со стадии легирования, были обучены линейные модели:
  • линейная регрессия,
  • стохастический градиентный спуск,
  • гребневая регрессия,
  • регрессия LASSO,

а также модели, основанные на использовании деревьев решений:

  • дерево решений,
  • случайный лес,
  • градиентный бустинг sklearn,
  • градиентный бустинг LightGBM,
  • градиентный бустинг XGBoost,
  • градиентный бустинг CatBoost.
  1. Для сравнения алгоритмов были обучены простые модели, предсказывающие значение начальной температуры расплава и среднее значение конечной температуры.

  2. Для каждого алгоритма было обучено несколько моделей с различными гиперпараметрами.

  3. Критерием отбора моделей было значение среднего абсолютного отклонения (MAE) предсказания конечной температуры расплава, полученного в результате проведения кросс-валидации. Пороговое значение MAE установлено на уровне 6,8 $^{\circ}$C.

  4. Простые модели не обеспечивают высокого качества предсказания, значение MAE для них составляет 8 и 19 $^{\circ}$C. Остальные модели обеспечивают высокое качество предсказания — значение MAE на уровне 6,1–6,5 $^{\circ}$C (кроме модели решающего дерева).

Модель и её параметры MAE, $^{\circ}$C
Простая модель
– предсказывающая значение начальной температуры 19,11
– предсказывающая среднее арифметическое значение конечной температуры 8,24
Линейная регрессия 6,15
Стохастический градиентный спуск 6,11
– альфа: 0,001, начальная скорость обучения: 0,01, порог остановки обучения: 0,1
Гребневая регрессия 6,13
– альфа: 10, максимальное число итераций: 100, порог остановки обучения: 0,0001
Регрессия LASSO 6,07
– альфа: 0,1, максимальное число итераций: 1000, порог остановки обучения: 0,00001
Дерево решений 7,49
– глубина дерева: 11, минимальное число листьев: 30, минимальное количество выборок: 3
Случайный лес 6,48
– число деревьев: 170, глубина дерева: None
Градиентный бустинг sklearn 6,13
– число итераций: 200, скорость обучения: 0,1
LightGBM 6,28
– число итераций: 1000, скорость обучения: 0,01
XGBoost 6,33
– число итераций: 200, скорость обучения: 0,05
CatBoost 6,07
– число итераций: 500, скорость обучения: 0,05
  1. Наилучшие показатели качества демонстрирует модель регрессии LASSO с максимальным числом итераций — 1000, альфой — 0,1 и порогом остановки обучения — 0,00001, с зафиксированной псевдослучайностью (random_state=250923), обученная на масштабированных данных. Значение MAE, полученное в результате проведения кросс-валидации, равно 6,1 $^{\circ}$C. Значение MAE на тестовой выборке равно 5,9 $^{\circ}$C.

Отчёт по решению¶

  1. Проект выполнен в соответствии с планом проведения работ. Все поставленные задачи выполнены, цель достигнута. Построена модель, прогнозирующая температуру расплава стали после окончания стадии легирования.
  2. Данные, полученные с предприятия, были описаны и проанализированы с применением статистических методов.
  3. Для целей обучения алгоритмов были отобраны данные пяти наборов данных из семи. Остальные два содержали сведения об отметках времени внесения легирующих добавок и не были использованы в связи с тем, что хронометрические средства измерения на производстве не синхронизированы.
  4. В наборах данных, полученных с производства, присутствовали аномальные значения:
  • температура расплава меньше температуры плавления стали (менее 1300 $^{\circ}$C);
  • отрицательные значения реактивной мощности.


Все записи о партиях с аномальными значениями были удалены из всех наборов данных.
5. Наборы данных, полученные с производства, содержали пропуски среди значений:

  • температуры расплава;
  • массы сыпучих материалов;
  • массы проволочных материалов.


Все записи о партиях с пропущенными значениями температуры расплава были удалены из всех наборов данных.
Все пропуски среди значений массы сыпучих и проволочных материалов заполнены нулём.
6. На основе данных, полученных на производстве, были сгенерированы производные признаки.

  • На основе данных о работе электродов были рассчитаны значения признаков:
    • full_power (полная мощность) из каждой пары значений признаков Активная мощность и Реактивная мощность;
    • power_factor (коэффициент мощности) из каждой пары значений Активная мощность и full_power;
    • heating_time (время подогрева) из каждой пары значений признаков Конец нагрева дугой и Начало нагрева дугой;
    • energy (потреблённая энергия) из каждой пары значений признаков full_power и heating_time.
  • На основе данных о вносимых сыпучих и проволочных материалах были рассчитаны значения признаков:
    • bulk_sum (общая масса вносимых сыпучих материалов) из всех значений признаков bulk N (где номер N изменялся от 1 до 15, включительно) для каждой записи;
    • bulk_count (количество видов вносимых сыпучих материалов) из всех ненулевых значений массы для каждой записи;
    • wire_bulk (общая масса вносимых проволочных материалов) из всех значений признаков wire N (где номер N изменялся от 1 до 9, включительно) для каждой записи;
    • wire_count (количество видов вносимых проволочных материалов) из всех ненулевых значений массы для каждой записи.
  1. Для целей обучения алгоритмов был собран набор данных, в котором в одной строке находились сведения об одной выпускаемой с предприятия партии стали. Таким образом, одна строка отражала характеристики одной партии.
  2. Для сведения данных в один набор в качестве ключа использовался номер партии key.
  3. Все объединения данных производились через внутреннее присоединение (inner join). Благодаря использованию такого объединения в наборе данных для обучения отсутствовали пропуски.
  4. В набор данных для обучения вошли:
  • сведения о партии:
    • key — номер партии;
  • сведения о температуре расплава, извлечённые с помощью агрегирующих функций:
    • first_temperature — начальная температура расплава,
    • last_temperature— конечная температура расплава;
  • сведения о времени стадии легирования, полученные как разность между первым измерением температуры и последним (из данных признака Время замера)
    • process_time — время проведения процедуры легирования;
  • сведения о полной мощности, полученные с помощью агрегирующих функций:
    • full_power_sum — суммарная полная мощность на партию,
    • full_power_avg — среднее значение полной мощности на одну операцию подогрева,
    • full_power_min — минимальное значение полной мощности на одну операцию подогрева,
    • full_power_max — максимальное значение полной мощности на одну операцию подогрева;
  • сведения об активной мощности, полученные с помощью агрегирующих функций:
    • active_power_avg — среднее значение активной мощности на одну операцию подогрева,
    • active_power_min — минимальное значение активной мощности на одну операцию подогрева,
    • active_power_max — максимальное значение активной мощности на одну операцию подогрева;
  • сведения о реактивной мощности, полученные с помощью агрегирующих функций:
    • reactive_power_avg — среднее значение реактивной мощности на одну операцию подогрева,
    • reactive_power_min — минимальное значение реактивной мощности на одну операцию подогрева,
    • reactive_power_max — максимальное значение реактивной мощности на одну операцию подогрева;
  • сведения о коэффициенте мощности, полученные с помощью агрегирующих функций:
    • power_factor_avg — среднее значение коэффициента мощности на одну операцию подогрева,
    • power_factor_min — минимальное значение коэффициента мощности на одну операцию подогрева,
    • power_factor_max — максимальное значение коэффициента мощности на одну операцию подогрева;
  • сведения о времени передачи энергии от электродов расплаву, полученные с помощью агрегирующих функций:
    • heating_time_sum — суммарное время передачи энергии на партию,
    • heating_time_avg — среднее значение времени передачи энергии на одну операцию подогрева,
    • heating_time_min — минимальное значение времени передачи энергии на одну операцию подогрева,
    • heating_time_max — максимальное значение времени передачи энергии на одну операцию подогрева;
  • сведения о переданной энергии расплаву, полученные с помощью агрегирующих функций:
    • energy_sum — суммарная переданная энергия на партию,
    • energy_avg — среднее значение переданной энергии на одну операцию подогрева,
    • energy_min — минимальное значение переданной энергии на одну операцию подогрева,
    • energy_max — максимальное значение переданной энергии на одну операцию подогрева;
  • сведения о подаваемом инертном газе:
    • gas — объём пропущенного через расплав инертного газа;
  • сведения о внесённых легирующих добавках:
    • bulk_N — масса сыпучего материала номер N (где N изменяется от 1 до 15, включительно),
    • bulk_sum — общая масса сыпучих материалов, внесённых в расплав,
    • bulk_count — количество разных видов сыпучих материалов, внесённых в расплав,
    • wire_N — масса проволочного материала номер N (где N изменяется от 1 до 9, включительно),
    • wire_sum — общая масса проволочных материалов, внесённых в расплав,
    • wire_count — количество разных видов проволочных материалов, внесённых в расплав.
  1. Проведён исследовательский анализ данных. С помощью методов описательной статистики охарактеризованы распределения значений признаков, собранных в наборе данных для обучения.
  2. Проведением корреляционного анализа была охарактеризована сила и направление линейной связи между признаками, собранными в наборе данных для обучения.
  3. По результатам проведения корреляционного анализа выявлены признаки, обладающие очень сильной и сильной положительной линейной связью. Часть признаков, линейная связь которых с другими признаками характеризовалась коэффициентом корреляции Пирсона, равным не менее 0,8, удалена из набора данных для обучения. Это признаки:
  • active_power_avg,
  • active_power_min,
  • active_power_max,
  • reactive_power_avg,
  • reactive_power_min,
  • reactive_power_max,
  • heating_count,
  • energy_sum,
  • bulk_sum,
  • wire_8.
  1. Из итогового набора данных также были удалены сведения о номере партии (признак key).
  2. Итоговый набор данных для обучения алгоритмов и построения моделей был разделён на две выборки — обучающую и тестовую — в отношении 3 : 1, соответственно. Из данных выделен целевой признак last_temperature в целевую переменную.
  3. Перед непосредственной передачей данных алгоритму машинного обучения значения всех признаков подвергались масштабированию с использованием функции StandardScaler.
  4. Масштабирование и последующее обучение алгоритма производились с использованием конвейера Pipeline.
  5. Для целей предсказания конечной температуры расплава стали, выходящего со стадии легирования, были обучены линейные модели:
  • линейная регрессия,
  • стохастический градиентный спуск,
  • гребневая регрессия,
  • регрессия LASSO,


а также модели, основанные на использовании деревьев решений:

  • дерево решений,
  • случайный лес,
  • градиентный бустинг sklearn,
  • градиентный бустинг LightGBM,
  • градиентный бустинг XGBoost,
  • градиентный бустинг CatBoost.
  1. Для сравнения алгоритмов были обучены простые модели, предсказывающие значение начальной температуры расплава и среднее арифметическое значение конечной температуры.
  2. В качестве метрики качества моделей использовалось среднее абсолютное отклонение (MAE). Пороговое значение MAE установлено равным 6,8 $^{\circ}$C.
  3. Оценка качества обученной модели проведена с использованием кросс-валидации, разделением обучающих данных на 3 подвыборки. Подбор параметров модели осуществлялся случайным поиском с применением функции RandomizedSearchCV.
  4. Случайный поиск параметров модели производился из следующих значений гиперпараметров:
  • для модели стохастического градиентного спуска:
    • alpha: {$10^n$}, где $n\in[-6, 1], n\in\Bbb{Z}$,
    • tol: {$10^n$}, где $n\in[-5, 1], n\in\Bbb{Z}$,
    • eta0: {$10^n$}, где $n\in[-3, 1], n\in\Bbb{Z}$;
  • для модели гребневой регрессии:
    • alpha: {$10^n$}, где $n\in[-2, 2], n\in\Bbb{Z}$,
    • tol: {$10^n$}, где $n\in[-5, 1], n\in\Bbb{Z}$,
    • max_iter: {None, $10^n$}, где $n\in[1, 3], n\in\Bbb{Z}$;
  • для модели регрессии LASSO:
    • alpha: {$10^n$}, где $n\in[-3, 3], n\in\Bbb{Z}$,
    • tol: {$10^n$}, где $n\in[-5, 1], n\in\Bbb{Z}$,
    • max_iter: {$10^n$}, где $n\in[1, 6], n\in\Bbb{Z}$;
  • для модели дерева решений:
    • max_depth: {None, $n$}, где $n\in[1, 30], n\in\Bbb{Z}$,
    • min_samples_leaf: {$n$}, где $n\in[1, 30], n\in\Bbb{Z}$,
    • min_samples_split: {$n$}, где $n\in[2, 10], n\in\Bbb{Z}$;
  • для модели случайного леса:
    • n_estimators: {$10\times{n}$}, где $n\in[1, 30], n\in\Bbb{Z}$,
    • max_depth: {None, $n$}, где $n\in[1, 10], n\in\Bbb{Z}$;
  • для моделей градиентного бустинга (scikit_learn, LightGBM, XGBoost, CatBoost):
    • n_estimators: {10, 20, 50, 100, 200, 500, 1000},
    • learning_rate: {0,005, 0,01, 0,05, 0,1, 0,2}.
  1. Наилучшие показатели качества демонстрирует:
  • модель регрессии LASSO с
    • максимальным числом итераций (max_iter) — 1000,
    • альфой (alpha) — 0,1,
    • порогом остановки обучения (tol) — 0,00001,
    • зафиксированной псевдослучайностью (random_state=250923).
  1. Значение MAE лучшей модели на тестовой выборке равно 5,9 $^{\circ}$C.
  2. Для улучшения качества предсказания рекомендуется:
  • синхронизировать во времени сбор данных на производстве, чтобы использовать для обучения все возможные сведения о легировании каждой партии и не отбрасывать часть из них;
  • обеспечивать качественный сбор, хранение и перенос данных из контрольных точек на технологической линии в базу данных, чтобы предотвратить потерю и искажение значений;
  • обеспечить контроль качества работы средств измерения на стадии легирования для предотвращения искажения измеряемых значений средством измерения;
  • увеличить количество наблюдений, чтобы увеличить объём данных для обучения алгоритмов;
  • если возможно, увеличить количество технологических показателей, характеризующих стадию легирования;
  • применить дополнительные способы обработки данных для получения новых признаков из существующих (возможно, путём создания комбинированных признаков);
  • увеличить перечень гиперпараметров моделей и использовать расширенный набор множества их подбираемых значений;
  • использовать другие алгоритмы машинного обучения (возможно, с применением комбинирования алгоритмов).